Skip to content

Commit

Permalink
sql: support INSERT with partial UNIQUE WITHOUT INDEX constraints
Browse files Browse the repository at this point in the history
Uniqueness checks on INSERTs are now performed for partial UNIQUE
WITHOUT INDEX constraints. The semi-join filters in the uniqueness
checks filter out rows that do not satisfy the predicate. Rows on both
sides of the join are filtered. This is required to prevent duplicate
key violations from occurring for rows that do not satisfy the predicate
of the partial unique constraint.

The WithScan and Scan of the uniqueness check now produce all ordinary
table columns, rather than just the PK and unique columns, because
predicates may refer any columns in the table.

Informs #59195

There is no release note because these constraints are gated behind the
experimental_enable_unique_without_index_constraints session variable.

Release note: None
  • Loading branch information
mgartner committed Feb 15, 2021
1 parent bfab33e commit 1a47d15
Show file tree
Hide file tree
Showing 9 changed files with 1,961 additions and 959 deletions.
12 changes: 6 additions & 6 deletions pkg/ccl/logictestccl/testdata/logic_test/regional_by_row
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ vectorized: true
│ │
│ └── • lookup join (semi)
│ │ table: regional_by_row_table@primary
│ │ equality: (lookup_join_const_col_@24, column1) = (crdb_region,pk)
│ │ equality: (lookup_join_const_col_@22, column1) = (crdb_region,pk)
│ │ equality cols are key
│ │ pred: column15 != crdb_region
│ │
Expand All @@ -317,7 +317,7 @@ vectorized: true
│ │
│ └── • lookup join (semi)
│ │ table: regional_by_row_table@regional_by_row_table_b_key
│ │ equality: (lookup_join_const_col_@36, column4) = (crdb_region,b)
│ │ equality: (lookup_join_const_col_@37, column4) = (crdb_region,b)
│ │ equality cols are key
│ │ pred: (column1 != pk) OR (column15 != crdb_region)
│ │
Expand All @@ -335,7 +335,7 @@ vectorized: true
└── • lookup join (semi)
│ table: regional_by_row_table@new_idx
│ equality: (lookup_join_const_col_@49, column3, column4) = (crdb_region,a,b)
│ equality: (lookup_join_const_col_@52, column3, column4) = (crdb_region,a,b)
│ equality cols are key
│ pred: (column1 != pk) OR (column15 != crdb_region)
Expand Down Expand Up @@ -385,7 +385,7 @@ vectorized: true
│ │
│ └── • lookup join (semi)
│ │ table: regional_by_row_table@primary
│ │ equality: (lookup_join_const_col_@35, upsert_pk) = (crdb_region,pk)
│ │ equality: (lookup_join_const_col_@33, upsert_pk) = (crdb_region,pk)
│ │ equality cols are key
│ │ pred: column1 != crdb_region
│ │
Expand All @@ -403,7 +403,7 @@ vectorized: true
│ │
│ └── • lookup join (semi)
│ │ table: regional_by_row_table@regional_by_row_table_b_key
│ │ equality: (lookup_join_const_col_@47, column5) = (crdb_region,b)
│ │ equality: (lookup_join_const_col_@48, column5) = (crdb_region,b)
│ │ equality cols are key
│ │ pred: (upsert_pk != pk) OR (column1 != crdb_region)
│ │
Expand All @@ -421,7 +421,7 @@ vectorized: true
└── • lookup join (semi)
│ table: regional_by_row_table@new_idx
│ equality: (lookup_join_const_col_@60, column4, column5) = (crdb_region,a,b)
│ equality: (lookup_join_const_col_@63, column4, column5) = (crdb_region,a,b)
│ equality cols are key
│ pred: (upsert_pk != pk) OR (column1 != crdb_region)
Expand Down
43 changes: 43 additions & 0 deletions pkg/sql/logictest/testdata/logic_test/unique
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,49 @@ us-west foo 1 1
eu-west bar 2 2


# Insert some non-null data into a table with a partial unique without index
# constraint.
statement ok
INSERT INTO uniq_partial VALUES (1, 1), (1, -1), (2, 2)

# Partial unique constraint violation.
statement error pgcode 23505 pq: duplicate key value violates unique constraint "unique_a"\nDETAIL: Key \(a\)=\(1\) already exists\.
INSERT INTO uniq_partial VALUES (1, 3)

# No partial unique constraint violation because b <= 0.
statement ok
INSERT INTO uniq_partial VALUES (1, -3)

# Attempt to insert conflicting keys twice in the same statement.
statement error pgcode 23505 pq: duplicate key value violates unique constraint "unique_a"\nDETAIL: Key \(a\)=\(3\) already exists\.
INSERT INTO uniq_partial VALUES (3, 3), (3, 4)

# Attempt to insert one conflicting key and one non-conflicting key in the same
# statement.
statement error pgcode 23505 pq: duplicate key value violates unique constraint "unique_a"\nDETAIL: Key \(a\)=\(1\) already exists\.
INSERT INTO uniq_partial VALUES (1, 3), (3, 3)

# Insert some rows with NULL keys.
statement ok
INSERT INTO uniq_partial VALUES (NULL, 5), (5, 5), (NULL, 5)

# Insert with non-constant input.
statement error pgcode 23505 pq: duplicate key value violates unique constraint "unique_a"\nDETAIL: Key \(a\)=\(1\) already exists\.
INSERT INTO uniq_partial SELECT w, x FROM other

query II colnames,rowsort
SELECT * FROM uniq_partial
----
a b
1 1
1 -1
1 -3
2 2
5 5
NULL 5
NULL 5


# -- Tests with UPDATE --
subtest Update

Expand Down
Loading

0 comments on commit 1a47d15

Please sign in to comment.