Skip to content

Commit d83b3da

Browse files
committed
sql: allow setting schema_locked for newly created tables
Previously, there was a blanket ban on transactions setting schema_locked on newly craeted tables. This patch removes this limitation to make it easier to test this functionality in the schema changer workload. The reason this is safe is because no CDC change feed can be created for a new table in the same transaction. This also simplifies testing in our randomized workload. Informs: #144591 Release note: None
1 parent 0229d90 commit d83b3da

File tree

5 files changed

+34
-9
lines changed

5 files changed

+34
-9
lines changed

pkg/sql/alter_table.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -731,7 +731,7 @@ func (n *alterTableNode) startExec(params runParams) error {
731731
}
732732

733733
case *tree.AlterTableSetStorageParams:
734-
setter := tablestorageparam.NewSetter(n.tableDesc)
734+
setter := tablestorageparam.NewSetter(n.tableDesc, false /* isNewObject */)
735735
if err := storageparam.Set(
736736
params.ctx,
737737
params.p.SemaCtx(),
@@ -761,7 +761,7 @@ func (n *alterTableNode) startExec(params runParams) error {
761761
}
762762

763763
case *tree.AlterTableResetStorageParams:
764-
setter := tablestorageparam.NewSetter(n.tableDesc)
764+
setter := tablestorageparam.NewSetter(n.tableDesc, false /* isNewObject */)
765765
if err := storageparam.Reset(
766766
params.ctx,
767767
params.EvalContext(),

pkg/sql/create_table.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1420,8 +1420,7 @@ func NewTableDesc(
14201420
desc := tabledesc.InitTableDescriptor(
14211421
id, dbID, sc.GetID(), n.Table.Table(), creationTime, privileges, persistence,
14221422
)
1423-
1424-
setter := tablestorageparam.NewSetter(&desc)
1423+
setter := tablestorageparam.NewSetter(&desc, true /* isNewObject */)
14251424
if err := storageparam.Set(
14261425
ctx,
14271426
semaCtx,

pkg/sql/storageparam/indexstorageparam/index_storage_param.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,3 +223,9 @@ func (po *Setter) RunPostChecks() error {
223223

224224
return nil
225225
}
226+
227+
// IsNewTableObject implements the Setter interface.
228+
func (po *Setter) IsNewTableObject() bool {
229+
//Not applicable to indexes.
230+
panic(errors.AssertionFailedf("not-implemented for indexes"))
231+
}

pkg/sql/storageparam/storage_param.go

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ type Setter interface {
3434
// This allows checking whether multiple storage parameters together
3535
// form a valid configuration.
3636
RunPostChecks() error
37+
// IsNewTableObject returns true if the storage parameter is being set on a new
38+
// table.
39+
IsNewTableObject() bool
3740
}
3841

3942
// Set sets the given storage parameters using the
@@ -45,7 +48,7 @@ func Set(
4548
params tree.StorageParams,
4649
setter Setter,
4750
) error {
48-
if err := storageParamPreChecks(ctx, evalCtx, params, nil /* resetParams */); err != nil {
51+
if err := storageParamPreChecks(ctx, evalCtx, setter, params, nil /* resetParams */); err != nil {
4952
return err
5053
}
5154
for _, sp := range params {
@@ -92,7 +95,7 @@ func Set(
9295
func Reset(
9396
ctx context.Context, evalCtx *eval.Context, params []string, paramObserver Setter,
9497
) error {
95-
if err := storageParamPreChecks(ctx, evalCtx, nil /* setParam */, params); err != nil {
98+
if err := storageParamPreChecks(ctx, evalCtx, paramObserver, nil /* setParam */, params); err != nil {
9699
return err
97100
}
98101
for _, p := range params {
@@ -126,7 +129,11 @@ func SetFillFactor(ctx context.Context, evalCtx *eval.Context, key string, datum
126129
// storageParamPreChecks is where we specify pre-conditions for setting/resetting
127130
// storage parameters `param`.
128131
func storageParamPreChecks(
129-
ctx context.Context, evalCtx *eval.Context, setParams tree.StorageParams, resetParams []string,
132+
ctx context.Context,
133+
evalCtx *eval.Context,
134+
setter Setter,
135+
setParams tree.StorageParams,
136+
resetParams []string,
130137
) error {
131138
if setParams != nil && resetParams != nil {
132139
return errors.AssertionFailedf("only one of setParams and resetParams should be non-nil.")
@@ -152,7 +159,11 @@ func storageParamPreChecks(
152159
// change we make to the descriptor in the transaction, so we can uphold
153160
// the "one-version invariant" as discussed further in RFC
154161
// https://github.com/ajwerner/cockroach/blob/ajwerner/low-latency-rfc-take-3/docs/RFCS/20230328_low_latency_changefeeds.md
155-
if len(keys) > 1 || !evalCtx.TxnImplicit || !evalCtx.TxnIsSingleStmt {
162+
// For newly created tables we will allow schema_locked to be set upon creation,
163+
// since later operations cannot unset schema_locked (i.e. only implicit single
164+
// statement transactions are allowed to manipulate schema_locked, see
165+
// checkSchemaChangeIsAllowed).
166+
if !setter.IsNewTableObject() && (len(keys) > 1 || !evalCtx.TxnImplicit || !evalCtx.TxnIsSingleStmt) {
156167
return pgerror.Newf(pgcode.InvalidParameterValue, "%q can only be set/reset on "+
157168
"its own without other parameters in a single-statement implicit transaction.", key)
158169
}

pkg/sql/storageparam/tablestorageparam/table_storage_param.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,18 +36,22 @@ type Setter struct {
3636
// UpdatedRowLevelTTL is kept separate from the RowLevelTTL in TableDesc
3737
// in case changes need to be made in schema changer.
3838
UpdatedRowLevelTTL *catpb.RowLevelTTL
39+
40+
// NewObject bool tracks if this is a newly created object.
41+
NewObject bool
3942
}
4043

4144
var _ storageparam.Setter = (*Setter)(nil)
4245

4346
// NewSetter returns a new Setter.
44-
func NewSetter(tableDesc *tabledesc.Mutable) *Setter {
47+
func NewSetter(tableDesc *tabledesc.Mutable, isNewObject bool) *Setter {
4548
var updatedRowLevelTTL *catpb.RowLevelTTL
4649
if tableDesc.HasRowLevelTTL() {
4750
updatedRowLevelTTL = protoutil.Clone(tableDesc.GetRowLevelTTL()).(*catpb.RowLevelTTL)
4851
}
4952
return &Setter{
5053
TableDesc: tableDesc,
54+
NewObject: isNewObject,
5155
UpdatedRowLevelTTL: updatedRowLevelTTL,
5256
}
5357
}
@@ -60,6 +64,11 @@ func (po *Setter) RunPostChecks() error {
6064
return nil
6165
}
6266

67+
// IsNewTableObject implements the Setter interface.
68+
func (po *Setter) IsNewTableObject() bool {
69+
return po.NewObject
70+
}
71+
6372
func boolFromDatum(
6473
ctx context.Context, evalCtx *eval.Context, key string, datum tree.Datum,
6574
) (bool, error) {

0 commit comments

Comments
 (0)