Skip to content

Commit

Permalink
scbuildstmt: Implement ADD CONSTRAINT ... CHECK
Browse files Browse the repository at this point in the history
This commit implements `ADD CONSTRAINT ... CHECK`. Thanks to the
previous infrastructural work for enabling adding/dropping check
constraint, we only need to add code in the new schema changer builder.

It also enabled `ADD CONSTRAINT ... CHECK` to be on by default. It
requires us to turn off new schema changer in various tests bc those
tests depends on specific behavior/knobs of the old schema changer.
  • Loading branch information
Xiang-Gu committed Dec 8, 2022
1 parent fed9727 commit 6ac0367
Show file tree
Hide file tree
Showing 59 changed files with 2,229 additions and 555 deletions.
6 changes: 3 additions & 3 deletions pkg/bench/rttanalysis/testdata/benchmark_expectations
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ exp,benchmark
10,AlterRole/alter_role_with_1_option
13,AlterRole/alter_role_with_2_options
17,AlterRole/alter_role_with_3_options
10,AlterTableAddCheckConstraint/alter_table_add_1_check_constraint
10,AlterTableAddCheckConstraint/alter_table_add_2_check_constraints
10,AlterTableAddCheckConstraint/alter_table_add_3_check_constraints
15,AlterTableAddCheckConstraint/alter_table_add_1_check_constraint
15,AlterTableAddCheckConstraint/alter_table_add_2_check_constraints
15,AlterTableAddCheckConstraint/alter_table_add_3_check_constraints
16,AlterTableAddColumn/alter_table_add_1_column
16,AlterTableAddColumn/alter_table_add_2_columns
16,AlterTableAddColumn/alter_table_add_3_columns
Expand Down
23 changes: 14 additions & 9 deletions pkg/ccl/logictestccl/testdata/logic_test/redact_descriptor
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@ CREATE VIEW redacted_descriptors AS
FROM
system.descriptor;


# The legacy schema changer won't have the `indexIdForValidaiton` field set because it's only
# required for the new schema changer, hence we skip the config that uses only legacy
# schema changer.
skipif config local-legacy-schema-changer
query T
SELECT descriptor from redacted_descriptors where id = 'collate_partition'::REGCLASS;
----
Expand All @@ -47,8 +50,9 @@ SELECT descriptor from redacted_descriptors where id = 'collate_partition'::REGC
"columnIds": [
2
],
"constraintId": 2,
"constraintId": 4,
"expr": "b != '_':::STRING",
"indexIdForValidation": 2,
"name": "check_b"
}
],
Expand All @@ -67,6 +71,7 @@ SELECT descriptor from redacted_descriptors where id = 'collate_partition'::REGC
"id": 2,
"name": "b",
"nullable": true,
"pgAttributeNum": 2,
"type": {
"family": "StringFamily",
"oid": 25
Expand Down Expand Up @@ -95,21 +100,21 @@ SELECT descriptor from redacted_descriptors where id = 'collate_partition'::REGC
"modificationTime": {},
"name": "collate_partition",
"nextColumnId": 3,
"nextConstraintId": 3,
"nextConstraintId": 5,
"nextFamilyId": 1,
"nextIndexId": 2,
"nextMutationId": 2,
"nextIndexId": 4,
"nextMutationId": 1,
"parentId": 104,
"primaryIndex": {
"compositeColumnIds": [
1
],
"constraintId": 1,
"createdAtNanos": "0",
"constraintId": 2,
"createdExplicitly": true,
"encodingType": 1,
"foreignKey": {},
"geoConfig": {},
"id": 1,
"id": 2,
"interleave": {},
"keyColumnDirections": [
"ASC"
Expand Down Expand Up @@ -161,7 +166,7 @@ SELECT descriptor from redacted_descriptors where id = 'collate_partition'::REGC
"time": {}
},
"unexposedParentSchemaId": 105,
"version": "5"
"version": "9"
}
}

Expand Down
10 changes: 10 additions & 0 deletions pkg/ccl/schemachangerccl/backup_base_generated_test.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion pkg/cli/testdata/doctor/test_recreate_zipdir
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ SELECT crdb_internal.unsafe_upsert_descriptor(53, decode('0a83050a05757365727318
SELECT crdb_internal.unsafe_upsert_namespace_entry(52, 29, 'users', 53, true);
SELECT crdb_internal.unsafe_upsert_descriptor(54, decode('0aad070a0876656869636c65731836203428013a0042280a02696410011a0d080e100018003000508617600020003000680070007800800100880100980100422a0a046369747910021a0d0807100018003007509308600020003000680070007800800100880100980100422a0a047479706510031a0d0807100018003007509308600020013000680070007800800100880100980100422e0a086f776e65725f696410041a0d080e10001800300050861760002001300068007000780080010088010098010042330a0d6372656174696f6e5f74696d6510051a0d080510001800300050da08600020013000680070007800800100880100980100422c0a0673746174757310061a0d080710001800300750930860002001300068007000780080010088010098010042360a1063757272656e745f6c6f636174696f6e10071a0d080710001800300750930860002001300068007000780080010088010098010042290a0365787410081a0d081210001800300050da1d600020013000680070007800800100880100980100480952630a077072696d617279100118012204636974792202696430023001400040004a10080010001a00200028003000380040005a007a0408002000800100880100900101980100a20106080012001800a80100b20100ba0100c00100c80100d00100e001005a89010a2576656869636c65735f6175746f5f696e6465785f666b5f636974795f7265665f75736572731002180022046369747922086f776e65725f6964300230043801400040004a10080010001a00200028003000380040005a007a0408002000800100880100900101980100a20106080012001800a80100b20100ba0100c00100c80100d00100e0010060036a210a0b0a0561646d696e100218000a0a0a04726f6f74100218001204726f6f741801800102880103980100b201650a077072696d61727910001a0269641a04636974791a04747970651a086f776e65725f69641a0d6372656174696f6e5f74696d651a067374617475731a1063757272656e745f6c6f636174696f6e1a03657874200120022003200420052006200720082800b80101c20100e80100f2010408001200f801008002009202009a0200a202290836100210041802180120352a11666b5f636974795f7265665f757365727330003800400048007000aa02340837100310051802180120362a1c666b5f76656869636c655f636974795f7265665f76656869636c657330023800400048007000b20200b80200c0021dc80200e00200800300880300a80300b00300', 'hex'), true);
SELECT crdb_internal.unsafe_upsert_namespace_entry(52, 29, 'vehicles', 54, true);
SELECT crdb_internal.unsafe_upsert_descriptor(55, decode('0ac30a0a0572696465731837203428013a0042280a02696410011a0d080e100018003000508617600020003000680070007800800100880100980100422a0a046369747910021a0d080710001800300750930860002000300068007000780080010088010098010042320a0c76656869636c655f6369747910031a0d0807100018003007509308600020013000680070007800800100880100980100422e0a0872696465725f696410041a0d080e10001800300050861760002001300068007000780080010088010098010042300a0a76656869636c655f696410051a0d080e10001800300050861760002001300068007000780080010088010098010042330a0d73746172745f6164647265737310061a0d080710001800300750930860002001300068007000780080010088010098010042310a0b656e645f6164647265737310071a0d080710001800300750930860002001300068007000780080010088010098010042300a0a73746172745f74696d6510081a0d080510001800300050da08600020013000680070007800800100880100980100422e0a08656e645f74696d6510091a0d080510001800300050da08600020013000680070007800800100880100980100422d0a07726576656e7565100a1a0d08031002180a300050a40d600020013000680070007800800100880100980100480b52630a077072696d617279100118012204636974792202696430023001400040004a10080010001a00200028003000380040005a007a0408002000800100880100900101980100a20106080012001800a80100b20100ba0100c00100c80100d00100e001005a86010a2272696465735f6175746f5f696e6465785f666b5f636974795f7265665f757365727310021800220463697479220872696465725f6964300230043801400040004a10080010001a00200028003000380040005a007a0408002000800100880100900101980100a20106080012001800a80100b20100ba0100c00100c80100d00100e001005a9d010a2d72696465735f6175746f5f696e6465785f666b5f76656869636c655f636974795f7265665f76656869636c657310031800220c76656869636c655f63697479220a76656869636c655f69643003300538023801400040004a10080010001a00200028003000380040005a007a0408002000800100880100900101980100a20106080012001800a80100b20100ba0100c00100c80100d00100e0010060046a210a0b0a0561646d696e100218000a0a0a04726f6f74100218001204726f6f741801800103880103980100a2013a0a1376656869636c655f63697479203d20636974791217636865636b5f76656869636c655f636974795f63697479180028022803300038004000b2018a010a077072696d61727910001a0269641a04636974791a0c76656869636c655f636974791a0872696465725f69641a0a76656869636c655f69641a0d73746172745f616464726573731a0b656e645f616464726573731a0a73746172745f74696d651a08656e645f74696d651a07726576656e7565200120022003200420052006200720082009200a2800b80101c20100e80100f2010408001200f801008002009202009a0200a202290837100210041802180120352a11666b5f636974795f7265665f757365727330003800400048007000a202340837100310051802180120362a1c666b5f76656869636c655f636974795f7265665f76656869636c657330003800400048007000aa02290838100110021802180120372a11666b5f636974795f7265665f726964657330023800400048007000b20200b80200c0021dc80200e00200800300880300a80300b00300', 'hex'), true);
SELECT crdb_internal.unsafe_upsert_descriptor(55, decode('0ac50a0a0572696465731837203428013a0042280a02696410011a0d080e100018003000508617600020003000680070007800800100880100980100422a0a046369747910021a0d080710001800300750930860002000300068007000780080010088010098010042320a0c76656869636c655f6369747910031a0d0807100018003007509308600020013000680070007800800100880100980100422e0a0872696465725f696410041a0d080e10001800300050861760002001300068007000780080010088010098010042300a0a76656869636c655f696410051a0d080e10001800300050861760002001300068007000780080010088010098010042330a0d73746172745f6164647265737310061a0d080710001800300750930860002001300068007000780080010088010098010042310a0b656e645f6164647265737310071a0d080710001800300750930860002001300068007000780080010088010098010042300a0a73746172745f74696d6510081a0d080510001800300050da08600020013000680070007800800100880100980100422e0a08656e645f74696d6510091a0d080510001800300050da08600020013000680070007800800100880100980100422d0a07726576656e7565100a1a0d08031002180a300050a40d600020013000680070007800800100880100980100480b52630a077072696d617279100118012204636974792202696430023001400040004a10080010001a00200028003000380040005a007a0408002000800100880100900101980100a20106080012001800a80100b20100ba0100c00100c80100d00100e001005a86010a2272696465735f6175746f5f696e6465785f666b5f636974795f7265665f757365727310021800220463697479220872696465725f6964300230043801400040004a10080010001a00200028003000380040005a007a0408002000800100880100900101980100a20106080012001800a80100b20100ba0100c00100c80100d00100e001005a9d010a2d72696465735f6175746f5f696e6465785f666b5f76656869636c655f636974795f7265665f76656869636c657310031800220c76656869636c655f63697479220a76656869636c655f69643003300538023801400040004a10080010001a00200028003000380040005a007a0408002000800100880100900101980100a20106080012001800a80100b20100ba0100c00100c80100d00100e0010060046a210a0b0a0561646d696e100218000a0a0a04726f6f74100218001204726f6f741801800103880103980100a2013c0a1376656869636c655f63697479203d20636974791217636865636b5f76656869636c655f636974795f636974791800280228033000380040004800b2018a010a077072696d61727910001a0269641a04636974791a0c76656869636c655f636974791a0872696465725f69641a0a76656869636c655f69641a0d73746172745f616464726573731a0b656e645f616464726573731a0a73746172745f74696d651a08656e645f74696d651a07726576656e7565200120022003200420052006200720082009200a2800b80101c20100e80100f2010408001200f801008002009202009a0200a202290837100210041802180120352a11666b5f636974795f7265665f757365727330003800400048007000a202340837100310051802180120362a1c666b5f76656869636c655f636974795f7265665f76656869636c657330003800400048007000aa02290838100110021802180120372a11666b5f636974795f7265665f726964657330023800400048007000b20200b80200c0021dc80200e00200800300880300a80300b00300', 'hex'), true);
SELECT crdb_internal.unsafe_upsert_namespace_entry(52, 29, 'rides', 55, true);
SELECT crdb_internal.unsafe_upsert_descriptor(56, decode('0ad2040a1a76656869636c655f6c6f636174696f6e5f686973746f726965731838203428013a00422a0a046369747910011a0d0807100018003007509308600020003000680070007800800100880100980100422d0a07726964655f696410021a0d080e100018003000508617600020003000680070007800800100880100980100422f0a0974696d657374616d7010031a0d080510001800300050da0860002000300068007000780080010088010098010042290a036c617410041a0d080210401800300050bd05600020013000680070007800800100880100980100422a0a046c6f6e6710051a0d080210401800300050bd05600020013000680070007800800100880100980100480652770a077072696d617279100118012204636974792207726964655f6964220974696d657374616d703001300230034000400040004a10080010001a00200028003000380040005a007a0408002000800100880100900101980100a20106080012001800a80100b20100ba0100c00100c80100d00100e0010060026a210a0b0a0561646d696e100218000a0a0a04726f6f74100218001204726f6f741801800102880103980100b2013c0a077072696d61727910001a04636974791a07726964655f69641a0974696d657374616d701a036c61741a046c6f6e67200120022003200420052800b80101c20100e80100f2010408001200f801008002009202009a0200a202290838100110021802180120372a11666b5f636974795f7265665f726964657330003800400048007000b20200b80200c0021dc80200e00200800300880300a80300b00300', 'hex'), true);
SELECT crdb_internal.unsafe_upsert_namespace_entry(52, 29, 'vehicle_location_histories', 56, true);
Expand Down
4 changes: 2 additions & 2 deletions pkg/sql/backfill.go
Original file line number Diff line number Diff line change
Expand Up @@ -1546,7 +1546,7 @@ func ValidateCheckConstraint(

return ie.WithSyntheticDescriptors([]catalog.Descriptor{tableDesc}, func() error {
return validateCheckExpr(ctx, &semaCtx, txn, sessionData, checkConstraint.GetExpr(),
tableDesc.(*tabledesc.Mutable), ie)
tableDesc.(*tabledesc.Mutable), ie, checkConstraint.GetIndexIDForValidation())
})
})
}
Expand Down Expand Up @@ -2604,7 +2604,7 @@ func validateCheckInTxn(
return ie.WithSyntheticDescriptors(
syntheticDescs,
func() error {
return validateCheckExpr(ctx, semaCtx, txn, sessionData, checkExpr, tableDesc, ie)
return validateCheckExpr(ctx, semaCtx, txn, sessionData, checkExpr, tableDesc, ie, 0)
})
}

Expand Down
5 changes: 5 additions & 0 deletions pkg/sql/backfill_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,11 @@ func (c constraintToUpdateForTest) IsNotNullColumnConstraint() bool {
return c.desc.NotNullColumn != 0
}

// GetIndexIDForValidation implements the catalog.CheckConstraint interface.
func (c constraintToUpdateForTest) GetIndexIDForValidation() descpb.IndexID {
return c.desc.Check.IndexIDForValidation
}

func TestShouldSkipConstraintValidation(t *testing.T) {
defer leaktest.AfterTest(t)()

Expand Down
4 changes: 4 additions & 0 deletions pkg/sql/catalog/descpb/structured.proto
Original file line number Diff line number Diff line change
Expand Up @@ -940,6 +940,10 @@ message TableDescriptor {
// constraints.
optional uint32 constraint_id = 8 [(gogoproto.customname) = "ConstraintID",
(gogoproto.casttype) = "ConstraintID", (gogoproto.nullable) = false];
// IndexIDForValidation is the index id to hint to the check constraint validation SQL query. It is used
// exclusively by sql.validateCheckExpr).
optional uint32 index_id_for_validation = 9 [(gogoproto.customname) = "IndexIDForValidation",
(gogoproto.casttype) = "IndexID", (gogoproto.nullable) = false];
}

repeated CheckConstraint checks = 20;
Expand Down
3 changes: 3 additions & 0 deletions pkg/sql/catalog/table_elements.go
Original file line number Diff line number Diff line change
Expand Up @@ -523,6 +523,9 @@ type CheckConstraint interface {
// IsHashShardingConstraint returns true iff this check constraint is
// associated with a hash-sharding column in this table.
IsHashShardingConstraint() bool

// GetIndexIDForValidation returns the index ID this constraint is supposed to check against.
GetIndexIDForValidation() descpb.IndexID
}

// ForeignKeyConstraint is an interface around a check constraint.
Expand Down
5 changes: 5 additions & 0 deletions pkg/sql/catalog/tabledesc/constraint.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,11 @@ func (c checkConstraint) IsHashShardingConstraint() bool {
return c.desc.FromHashShardedColumn
}

// GetIndexIDForValidation implements the catalog.CheckConstraint interface.
func (c checkConstraint) GetIndexIDForValidation() descpb.IndexID {
return c.desc.IndexIDForValidation
}

// GetConstraintID implements the catalog.Constraint interface.
func (c checkConstraint) GetConstraintID() descpb.ConstraintID {
return c.desc.ConstraintID
Expand Down
6 changes: 6 additions & 0 deletions pkg/sql/check.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ import (

// validateCheckExpr verifies that the given CHECK expression returns true
// for all the rows in the table.
// `indexIDForValidation`, if non-zero, is used to explicit hint the
// validation query to check against a specific index.
//
// It operates entirely on the current goroutine and is thus able to
// reuse an existing client.Txn safely.
Expand All @@ -51,6 +53,7 @@ func validateCheckExpr(
exprStr string,
tableDesc *tabledesc.Mutable,
ie sqlutil.InternalExecutor,
indexIDForValidation descpb.IndexID,
) error {
expr, err := schemaexpr.FormatExprForDisplay(ctx, tableDesc, exprStr, semaCtx, sessionData, tree.FmtParsable)
if err != nil {
Expand All @@ -59,6 +62,9 @@ func validateCheckExpr(
colSelectors := tabledesc.ColumnsSelectors(tableDesc.AccessibleColumns())
columns := tree.AsStringWithFlags(&colSelectors, tree.FmtSerializable)
queryStr := fmt.Sprintf(`SELECT %s FROM [%d AS t] WHERE NOT (%s) LIMIT 1`, columns, tableDesc.GetID(), exprStr)
if indexIDForValidation != 0 {
queryStr = fmt.Sprintf(`SELECT %s FROM [%d AS t]@[%d] WHERE NOT (%s) LIMIT 1`, columns, tableDesc.GetID(), indexIDForValidation, exprStr)
}
log.Infof(ctx, "validating check constraint %q with query %q", expr, queryStr)
rows, err := ie.QueryRowEx(
ctx,
Expand Down
Loading

0 comments on commit 6ac0367

Please sign in to comment.