Skip to content

Commit 7e40539

Browse files
craig[bot]rafiss
andcommitted
157834: sql: unset RBRUsingConstraint during rollback r=rafiss a=rafiss Previously, if a rollback dropped a constraint due to a FK validation error, it would never update the RBRUsingConstraint field even if the constraint being rolled back was referenced by that field. Now the field is cleared properly when needed. fixes cockroachdb#157832 Release note (bug fix): Fixed a bug that could cause a schema change to be stuck in the reverting state if the infer_rbr_region_col_using_constraint storage parameter was being set at the same time as adding a constraint that had a foreign key violation. Co-authored-by: Rafi Shamim <[email protected]>
2 parents e04fc04 + abf90df commit 7e40539

File tree

2 files changed

+69
-0
lines changed

2 files changed

+69
-0
lines changed

pkg/ccl/logictestccl/testdata/logic_test/regional_by_row_foreign_key

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2237,3 +2237,67 @@ DROP FUNCTION display_child;
22372237
DROP TABLE child;
22382238

22392239
subtest end
2240+
2241+
# ==============================================================================
2242+
# Verify that a foreign key violation causes the addition of the
2243+
# rbr_using_constraint to be reverted properly.
2244+
# ==============================================================================
2245+
2246+
subtest revert_fk_violation
2247+
2248+
statement ok
2249+
SET create_table_with_schema_locked = false;
2250+
2251+
statement ok
2252+
CREATE TABLE a (
2253+
id uuid NOT NULL PRIMARY KEY
2254+
) LOCALITY REGIONAL BY ROW
2255+
2256+
statement ok
2257+
CREATE TABLE b (
2258+
id uuid NOT NULL,
2259+
a_id uuid NULL,
2260+
CONSTRAINT b_pkey PRIMARY KEY (id ASC),
2261+
CONSTRAINT a_id_fk FOREIGN KEY (a_id) REFERENCES a (id)
2262+
) LOCALITY REGIONAL BY ROW
2263+
2264+
# Insert data that will cause a foreign key violation when we try to add the composite FK.
2265+
statement ok
2266+
INSERT INTO a (id, crdb_region) VALUES ('4227eceb-71d6-422c-808b-6a12ec8a1e54', 'us-east-1')
2267+
2268+
statement ok
2269+
INSERT INTO b (id, a_id, crdb_region) VALUES ('8f6ce660-423e-4823-8e41-bf001a007b46', '4227eceb-71d6-422c-808b-6a12ec8a1e54', 'ca-central-1')
2270+
2271+
# This statement should fail with a foreign key violation, and the schema change
2272+
# should properly revert without causing infinite retries due to the missing RBRUsingConstraint.
2273+
# Prior to the bugfix, the rollback logic would would drop the constraint but
2274+
# not clear the RBRUsingConstraint field, causing validation to fail during
2275+
# the rollback.
2276+
statement error pgcode 23503 pq: foreign key violation: "b" row crdb_region='ca-central-1', a_id='4227eceb-71d6-422c-808b-6a12ec8a1e54', id='8f6ce660-423e-4823-8e41-bf001a007b46' has no match in "a"
2277+
ALTER TABLE b
2278+
DROP CONSTRAINT a_id_fk,
2279+
ADD CONSTRAINT a_crdb_region_id_fk
2280+
FOREIGN KEY (crdb_region, a_id) REFERENCES a (crdb_region, id) ON UPDATE CASCADE ON DELETE CASCADE,
2281+
SET (infer_rbr_region_col_using_constraint = a_crdb_region_id_fk)
2282+
2283+
# Verify the tables are still functional after the failed schema change.
2284+
query I
2285+
SELECT count(*) FROM a
2286+
----
2287+
1
2288+
2289+
query I
2290+
SELECT count(*) FROM b
2291+
----
2292+
1
2293+
2294+
statement ok
2295+
DROP TABLE b CASCADE
2296+
2297+
statement ok
2298+
DROP TABLE a CASCADE
2299+
2300+
statement ok
2301+
RESET create_table_with_schema_locked;
2302+
2303+
subtest end

pkg/sql/schema_changer.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2531,6 +2531,11 @@ func (sc *SchemaChanger) maybeDropValidatingConstraint(
25312531
constraint.GetName(),
25322532
)
25332533
} else if constraint.AsForeignKey() != nil {
2534+
// If the constraint being dropped is the regional-by-row constraint,
2535+
// we must clear the reference to it.
2536+
if desc.RBRUsingConstraint == constraint.GetConstraintID() {
2537+
desc.RBRUsingConstraint = descpb.ConstraintID(0)
2538+
}
25342539
for i, fk := range desc.OutboundFKs {
25352540
if fk.Name == constraint.GetName() {
25362541
desc.OutboundFKs = append(desc.OutboundFKs[:i], desc.OutboundFKs[i+1:]...)

0 commit comments

Comments
 (0)