Skip to content

Commit 1a6136a

Browse files
committed
randgen: rework TableOpt to follow option pattern
This commit reworks randgen so that TableOpt follows the standard go option convention. This allows for spelling non-binary options like type filters or transformations. Release note: none
1 parent 1c2c92b commit 1a6136a

File tree

14 files changed

+111
-55
lines changed

14 files changed

+111
-55
lines changed

pkg/crosscluster/logical/logical_replication_job_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -913,7 +913,7 @@ func TestRandomTables(t *testing.T) {
913913
rng,
914914
tableName,
915915
1,
916-
randgen.TableOptSkipColumnFamilyMutations)
916+
[]randgen.TableOption{randgen.WithSkipColumnFamilyMutations()})
917917
stmt := tree.SerializeForDisplay(createStmt)
918918
t.Log(stmt)
919919
runnerA.Exec(t, stmt)

pkg/crosscluster/logical/udf_row_processor_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ func TestUDFWithRandomTables(t *testing.T) {
6060
rng,
6161
tableName,
6262
1,
63-
randgen.TableOptPrimaryIndexRequired|randgen.TableOptSkipColumnFamilyMutations,
63+
[]randgen.TableOption{randgen.WithPrimaryIndexRequired(), randgen.WithSkipColumnFamilyMutations()},
6464
)
6565
stmt := tree.SerializeForDisplay(createStmt)
6666
t.Log(stmt)

pkg/internal/sqlsmith/alter.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ func makeCreateSchema(s *Smither) (tree.Statement, bool) {
114114
}
115115

116116
func makeCreateTable(s *Smither) (tree.Statement, bool) {
117-
table := randgen.RandCreateTable(context.Background(), s.rnd, "", 0, randgen.TableOptNone)
117+
table := randgen.RandCreateTable(context.Background(), s.rnd, "", 0, nil)
118118
schemaOrd := s.rnd.Intn(len(s.schemas))
119119
schema := s.schemas[schemaOrd]
120120
table.Table = tree.MakeTableNameWithSchema(tree.Name(s.dbName), schema.SchemaName, s.name("tab"))

pkg/internal/sqlsmith/setup.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -129,12 +129,12 @@ func randTablesN(r *rand.Rand, n int, prefix string, isMultiRegion bool) []strin
129129
stmts = append(stmts, `SET CLUSTER SETTING sql.stats.forecasts.enabled = false;`)
130130

131131
// Create the random tables.
132-
opt := randgen.TableOptCrazyNames
132+
opts := []randgen.TableOption{randgen.WithCrazyNames()}
133133
if isMultiRegion {
134-
opt |= randgen.TableOptMultiRegion
134+
opts = append(opts, randgen.WithMultiRegion())
135135
}
136136
createTableStatements := randgen.RandCreateTables(
137-
context.Background(), r, "table", n, opt, randgen.StatisticsMutator,
137+
context.Background(), r, "table", n, opts, randgen.StatisticsMutator,
138138
randgen.PartialIndexMutator, randgen.ForeignKeyMutator,
139139
)
140140

pkg/sql/colenc/encode_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ func TestEncoderEqualityRand(t *testing.T) {
267267
rng, _ := randutil.NewTestRand()
268268
for i := 0; i < 100; i++ {
269269
tableName := fmt.Sprintf("t%d", i)
270-
ct := randgen.RandCreateTableWithName(ctx, rng, tableName, i, randgen.TableOptNone)
270+
ct := randgen.RandCreateTableWithName(ctx, rng, tableName, i, nil)
271271
tableDef := tree.Serialize(ct)
272272
r := sqlutils.MakeSQLRunner(db)
273273
r.Exec(t, tableDef)

pkg/sql/export/exportparquet_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ func TestRandomParquetExports(t *testing.T) {
199199
)
200200

201201
stmts := randgen.RandCreateTables(
202-
ctx, rng, tablePrefix, numTables, randgen.TableOptNone,
202+
ctx, rng, tablePrefix, numTables, nil,
203203
randgen.PartialIndexMutator, randgen.ForeignKeyMutator,
204204
)
205205

pkg/sql/randgen/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ go_library(
99
"expr.go",
1010
"mutator.go",
1111
"schema.go",
12+
"table_opt.go",
1213
"type.go",
1314
],
1415
importpath = "github.com/cockroachdb/cockroach/pkg/sql/randgen",

pkg/sql/randgen/schema.go

Lines changed: 34 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -102,24 +102,14 @@ func RandCreateCompositeType(rng *rand.Rand, name, alphabet string) tree.Stateme
102102
}
103103
}
104104

105-
type TableOpt uint8
106-
107-
const (
108-
TableOptNone TableOpt = 0
109-
TableOptPrimaryIndexRequired TableOpt = 1 << (iota - 1)
110-
TableOptSkipColumnFamilyMutations
111-
TableOptMultiRegion
112-
TableOptAllowPartiallyVisibleIndex
113-
TableOptCrazyNames
114-
)
115-
116-
func (t TableOpt) IsSet(o TableOpt) bool {
117-
return t&o == o
118-
}
119-
120105
// RandCreateTables creates random table definitions.
121106
func RandCreateTables(
122-
ctx context.Context, rng *rand.Rand, prefix string, num int, opt TableOpt, mutators ...Mutator,
107+
ctx context.Context,
108+
rng *rand.Rand,
109+
prefix string,
110+
num int,
111+
opts []TableOption,
112+
mutators ...Mutator,
123113
) []tree.Statement {
124114
if num < 1 {
125115
panic("at least one table required")
@@ -128,7 +118,7 @@ func RandCreateTables(
128118
// Make some random tables.
129119
tables := make([]tree.Statement, num)
130120
for i := 0; i < num; i++ {
131-
t := RandCreateTable(ctx, rng, prefix, i+1, opt)
121+
t := RandCreateTable(ctx, rng, prefix, i+1, opts)
132122
tables[i] = t
133123
}
134124

@@ -141,10 +131,10 @@ func RandCreateTables(
141131

142132
// RandCreateTable creates a random CreateTable definition.
143133
func RandCreateTable(
144-
ctx context.Context, rng *rand.Rand, prefix string, tableIdx int, opt TableOpt,
134+
ctx context.Context, rng *rand.Rand, prefix string, tableIdx int, opts []TableOption,
145135
) *tree.CreateTable {
146136
return RandCreateTableWithColumnIndexNumberGenerator(
147-
ctx, rng, prefix, tableIdx, opt, nil, /* generateColumnIndexNumber */
137+
ctx, rng, prefix, tableIdx, opts, nil, /* generateColumnIndexNumber */
148138
)
149139
}
150140

@@ -161,26 +151,27 @@ func RandCreateTableWithColumnIndexNumberGenerator(
161151
rng *rand.Rand,
162152
prefix string,
163153
tableIdx int,
164-
opt TableOpt,
154+
opts []TableOption,
165155
generateColumnIndexSuffix func() string,
166156
) *tree.CreateTable {
157+
options := applyOptions(opts)
167158
var name string
168-
if opt.IsSet(TableOptCrazyNames) {
159+
if options.crazyNames {
169160
g := randident.NewNameGenerator(&nameGenCfg, rng, prefix)
170161
name = g.GenerateOne(strconv.Itoa(tableIdx))
171162
} else {
172163
name = fmt.Sprintf("%s%d", prefix, tableIdx)
173164
}
174165
return randCreateTableWithColumnIndexNumberGeneratorAndName(
175-
ctx, rng, name, tableIdx, opt, generateColumnIndexSuffix,
166+
ctx, rng, name, tableIdx, opts, generateColumnIndexSuffix,
176167
)
177168
}
178169

179170
func RandCreateTableWithName(
180-
ctx context.Context, rng *rand.Rand, tableName string, tableIdx int, opt TableOpt,
171+
ctx context.Context, rng *rand.Rand, tableName string, tableIdx int, opts []TableOption,
181172
) *tree.CreateTable {
182173
return randCreateTableWithColumnIndexNumberGeneratorAndName(
183-
ctx, rng, tableName, tableIdx, opt, nil, /* generateColumnIndexSuffix */
174+
ctx, rng, tableName, tableIdx, opts, nil, /* generateColumnIndexSuffix */
184175
)
185176
}
186177

@@ -189,9 +180,10 @@ func randCreateTableWithColumnIndexNumberGeneratorAndName(
189180
rng *rand.Rand,
190181
tableName string,
191182
tableIdx int,
192-
opt TableOpt,
183+
opts []TableOption,
193184
generateColumnIndexSuffix func() string,
194185
) *tree.CreateTable {
186+
options := applyOptions(opts)
195187
// columnDefs contains the list of Columns we'll add to our table.
196188
nColumns := randutil.RandIntInRange(rng, 1, 20)
197189
columnDefs := make([]*tree.ColumnTableDef, 0, nColumns)
@@ -211,24 +203,24 @@ func randCreateTableWithColumnIndexNumberGeneratorAndName(
211203
nComputedColumns := randutil.RandIntInRange(rng, 0, (nColumns+1)/2)
212204
nNormalColumns := nColumns - nComputedColumns
213205
for i := 0; i < nNormalColumns; i++ {
214-
columnDef := randColumnTableDef(rng, tableIdx, colSuffix(i), opt)
206+
columnDef := randColumnTableDef(rng, tableIdx, colSuffix(i), opts)
215207
columnDefs = append(columnDefs, columnDef)
216208
defs = append(defs, columnDef)
217209
}
218210

219211
// Make defs for computed columns.
220212
normalColDefs := columnDefs
221213
for i := nNormalColumns; i < nColumns; i++ {
222-
columnDef := randComputedColumnTableDef(rng, normalColDefs, tableIdx, colSuffix(i), opt)
214+
columnDef := randComputedColumnTableDef(rng, normalColDefs, tableIdx, colSuffix(i), opts)
223215
columnDefs = append(columnDefs, columnDef)
224216
defs = append(defs, columnDef)
225217
}
226218

227219
// Make a random primary key with high likelihood.
228220
var pk *tree.IndexTableDef
229-
if opt.IsSet(TableOptPrimaryIndexRequired) || (rng.Intn(8) != 0) {
221+
if options.primaryIndexRequired || (rng.Intn(8) != 0) {
230222
for {
231-
indexDef, ok := randIndexTableDefFromCols(ctx, rng, columnDefs, tableName, true /* isPrimaryIndex */, opt)
223+
indexDef, ok := randIndexTableDefFromCols(ctx, rng, columnDefs, tableName, true /* isPrimaryIndex */, opts)
232224
canUseIndex := ok && indexDef.Type.CanBePrimary()
233225
if canUseIndex {
234226
// Although not necessary for Cockroach to function correctly,
@@ -248,7 +240,7 @@ func randCreateTableWithColumnIndexNumberGeneratorAndName(
248240
IndexTableDef: indexDef,
249241
})
250242
}
251-
if canUseIndex || !opt.IsSet(TableOptPrimaryIndexRequired) {
243+
if canUseIndex || !options.primaryIndexRequired {
252244
break
253245
}
254246
}
@@ -257,7 +249,7 @@ func randCreateTableWithColumnIndexNumberGeneratorAndName(
257249
// Make indexes.
258250
nIdxs := rng.Intn(10)
259251
for i := 0; i < nIdxs; i++ {
260-
indexDef, ok := randIndexTableDefFromCols(ctx, rng, columnDefs, tableName, false /* isPrimaryIndex */, opt)
252+
indexDef, ok := randIndexTableDefFromCols(ctx, rng, columnDefs, tableName, false /* isPrimaryIndex */, opts)
261253
if !ok {
262254
continue
263255
}
@@ -291,7 +283,7 @@ func randCreateTableWithColumnIndexNumberGeneratorAndName(
291283
indexDef.Invisibility.Value = 0.0
292284
if notvisible := rng.Intn(6) == 0; notvisible {
293285
indexDef.Invisibility.Value = 1.0
294-
if opt.IsSet(TableOptAllowPartiallyVisibleIndex) {
286+
if options.allowPartiallyVisibleIndex {
295287
if rng.Intn(2) == 0 {
296288
indexDef.Invisibility.Value = 1 - rng.Float64()
297289
indexDef.Invisibility.FloatProvided = true
@@ -309,7 +301,7 @@ func randCreateTableWithColumnIndexNumberGeneratorAndName(
309301
}
310302

311303
// Create some random column families.
312-
if !opt.IsSet(TableOptSkipColumnFamilyMutations) && rng.Intn(2) == 0 {
304+
if !options.skipColumnFamilyMutations && rng.Intn(2) == 0 {
313305
ColumnFamilyMutator(rng, ret)
314306
}
315307

@@ -463,10 +455,11 @@ func PopulateTableWithRandData(
463455
// randColumnTableDef produces a random ColumnTableDef for a non-computed
464456
// column, with a random type and nullability.
465457
func randColumnTableDef(
466-
rng *rand.Rand, tableIdx int, colSuffix string, opt TableOpt,
458+
rng *rand.Rand, tableIdx int, colSuffix string, opts []TableOption,
467459
) *tree.ColumnTableDef {
460+
options := applyOptions(opts)
468461
var colName tree.Name
469-
if opt.IsSet(TableOptCrazyNames) {
462+
if options.crazyNames {
470463
g := randident.NewNameGenerator(&nameGenCfg, rng, fmt.Sprintf("col%d", tableIdx))
471464
colName = tree.Name(g.GenerateOne(colSuffix))
472465
} else {
@@ -501,9 +494,9 @@ func randComputedColumnTableDef(
501494
normalColDefs []*tree.ColumnTableDef,
502495
tableIdx int,
503496
colSuffix string,
504-
opt TableOpt,
497+
opts []TableOption,
505498
) *tree.ColumnTableDef {
506-
newDef := randColumnTableDef(rng, tableIdx, colSuffix, opt)
499+
newDef := randColumnTableDef(rng, tableIdx, colSuffix, opts)
507500
newDef.Computed.Computed = true
508501
newDef.Computed.Virtual = rng.Intn(2) == 0
509502

@@ -524,8 +517,9 @@ func randIndexTableDefFromCols(
524517
columnTableDefs []*tree.ColumnTableDef,
525518
tableName string,
526519
isPrimaryIndex bool,
527-
opt TableOpt,
520+
opts []TableOption,
528521
) (def tree.IndexTableDef, ok bool) {
522+
options := applyOptions(opts)
529523
cpy := make([]*tree.ColumnTableDef, len(columnTableDefs))
530524
copy(cpy, columnTableDefs)
531525
rng.Shuffle(len(cpy), func(i, j int) { cpy[i], cpy[j] = cpy[j], cpy[i] })
@@ -655,7 +649,7 @@ func randIndexTableDefFromCols(
655649
// not support partitioning.
656650
// TODO(harding): Allow partitioning the primary index. This will require
657651
// massaging the syntax.
658-
if !opt.IsSet(TableOptMultiRegion) && !isPrimaryIndex && !partitioningNotSupported && len(prefix) > 0 && rng.Intn(10) == 0 {
652+
if !options.multiRegion && !isPrimaryIndex && !partitioningNotSupported && len(prefix) > 0 && rng.Intn(10) == 0 {
659653
def.PartitionByIndex = &tree.PartitionByIndex{PartitionBy: &tree.PartitionBy{}}
660654
prefixLen := 1 + rng.Intn(len(prefix))
661655
def.PartitionByIndex.Fields = prefix[:prefixLen]
@@ -666,7 +660,7 @@ func randIndexTableDefFromCols(
666660
numExpressions := rng.Intn(10) + 1
667661
for i := 0; i < numPartitions; i++ {
668662
var partition tree.ListPartition
669-
if opt.IsSet(TableOptCrazyNames) {
663+
if options.crazyNames {
670664
partition.Name = tree.Name(g.GenerateOne(strconv.Itoa(i)))
671665
} else {
672666
partition.Name = tree.Name(fmt.Sprintf("%s_part_%d", tableName, i))

pkg/sql/randgen/schema_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ func TestPopulateTableWithRandData(t *testing.T) {
4646
numTables := 10
4747

4848
stmts := randgen.RandCreateTables(
49-
ctx, rng, tablePrefix, numTables, randgen.TableOptNone,
49+
ctx, rng, tablePrefix, numTables, nil,
5050
randgen.PartialIndexMutator, randgen.ForeignKeyMutator,
5151
)
5252

pkg/sql/randgen/table_opt.go

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// Copyright 2025 The Cockroach Authors.
2+
//
3+
// Use of this software is governed by the CockroachDB Software License
4+
// included in the /LICENSE file.
5+
6+
package randgen
7+
8+
// TableOption represents a single option for table generation.
9+
type TableOption func(*tableOptions)
10+
11+
type tableOptions struct {
12+
primaryIndexRequired bool
13+
skipColumnFamilyMutations bool
14+
multiRegion bool
15+
allowPartiallyVisibleIndex bool
16+
crazyNames bool
17+
}
18+
19+
// WithPrimaryIndexRequired requires that the table has a primary index.
20+
func WithPrimaryIndexRequired() TableOption {
21+
return func(o *tableOptions) {
22+
o.primaryIndexRequired = true
23+
}
24+
}
25+
26+
// WithSkipColumnFamilyMutations skips column family mutations.
27+
func WithSkipColumnFamilyMutations() TableOption {
28+
return func(o *tableOptions) {
29+
o.skipColumnFamilyMutations = true
30+
}
31+
}
32+
33+
// WithMultiRegion enables multi-region table generation.
34+
func WithMultiRegion() TableOption {
35+
return func(o *tableOptions) {
36+
o.multiRegion = true
37+
}
38+
}
39+
40+
// WithAllowPartiallyVisibleIndex allows partially visible indexes.
41+
func WithAllowPartiallyVisibleIndex() TableOption {
42+
return func(o *tableOptions) {
43+
o.allowPartiallyVisibleIndex = true
44+
}
45+
}
46+
47+
// WithCrazyNames enables generation of crazy table and column names.
48+
func WithCrazyNames() TableOption {
49+
return func(o *tableOptions) {
50+
o.crazyNames = true
51+
}
52+
}
53+
54+
// applyOptions applies the given options to a tableOptions struct.
55+
func applyOptions(opts []TableOption) tableOptions {
56+
var o tableOptions
57+
for _, opt := range opts {
58+
opt(&o)
59+
}
60+
return o
61+
}

0 commit comments

Comments
 (0)