github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/sqlbase/testutils.go (about) 1 // Copyright 2016 The Cockroach Authors. 2 // 3 // Use of this software is governed by the Business Source License 4 // included in the file licenses/BSL.txt. 5 // 6 // As of the Change Date specified in that file, in accordance with 7 // the Business Source License, use of this software will be governed 8 // by the Apache License, Version 2.0, included in the file 9 // licenses/APL.txt. 10 11 package sqlbase 12 13 import ( 14 "bytes" 15 "context" 16 gosql "database/sql" 17 "fmt" 18 "math" 19 "math/big" 20 "math/bits" 21 "math/rand" 22 "sort" 23 "strings" 24 "time" 25 "unicode" 26 27 "github.com/cockroachdb/apd" 28 "github.com/cockroachdb/cockroach/pkg/geo" 29 "github.com/cockroachdb/cockroach/pkg/keys" 30 "github.com/cockroachdb/cockroach/pkg/kv" 31 "github.com/cockroachdb/cockroach/pkg/roachpb" 32 "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" 33 "github.com/cockroachdb/cockroach/pkg/sql/types" 34 "github.com/cockroachdb/cockroach/pkg/util/bitarray" 35 "github.com/cockroachdb/cockroach/pkg/util/duration" 36 "github.com/cockroachdb/cockroach/pkg/util/ipaddr" 37 "github.com/cockroachdb/cockroach/pkg/util/json" 38 "github.com/cockroachdb/cockroach/pkg/util/log" 39 "github.com/cockroachdb/cockroach/pkg/util/randutil" 40 "github.com/cockroachdb/cockroach/pkg/util/timeofday" 41 "github.com/cockroachdb/cockroach/pkg/util/timeutil" 42 "github.com/cockroachdb/cockroach/pkg/util/timeutil/pgdate" 43 "github.com/cockroachdb/cockroach/pkg/util/uint128" 44 "github.com/cockroachdb/cockroach/pkg/util/uuid" 45 "github.com/cockroachdb/errors" 46 "github.com/lib/pq/oid" 47 ) 48 49 // This file contains utility functions for tests (in other packages). 50 51 // GetTableDescriptor retrieves a table descriptor directly from the KV layer. 52 func GetTableDescriptor( 53 kvDB *kv.DB, codec keys.SQLCodec, database string, table string, 54 ) *TableDescriptor { 55 // log.VEventf(context.TODO(), 2, "GetTableDescriptor %q %q", database, table) 56 // testutil, so we pass settings as nil for both database and table name keys. 57 dKey := NewDatabaseKey(database) 58 ctx := context.TODO() 59 gr, err := kvDB.Get(ctx, dKey.Key(codec)) 60 if err != nil { 61 panic(err) 62 } 63 if !gr.Exists() { 64 panic("database missing") 65 } 66 dbDescID := ID(gr.ValueInt()) 67 68 tKey := NewPublicTableKey(dbDescID, table) 69 gr, err = kvDB.Get(ctx, tKey.Key(codec)) 70 if err != nil { 71 panic(err) 72 } 73 if !gr.Exists() { 74 panic("table missing") 75 } 76 77 descKey := MakeDescMetadataKey(codec, ID(gr.ValueInt())) 78 desc := &Descriptor{} 79 ts, err := kvDB.GetProtoTs(ctx, descKey, desc) 80 if err != nil || (*desc == Descriptor{}) { 81 log.Fatalf(ctx, "proto with id %d missing. err: %v", gr.ValueInt(), err) 82 } 83 tableDesc := desc.Table(ts) 84 if tableDesc == nil { 85 return nil 86 } 87 err = tableDesc.MaybeFillInDescriptor(ctx, kvDB, codec) 88 if err != nil { 89 log.Fatalf(ctx, "failure to fill in descriptor. err: %v", err) 90 } 91 return tableDesc 92 } 93 94 // GetImmutableTableDescriptor retrieves an immutable table descriptor directly from the KV layer. 95 func GetImmutableTableDescriptor( 96 kvDB *kv.DB, codec keys.SQLCodec, database string, table string, 97 ) *ImmutableTableDescriptor { 98 return NewImmutableTableDescriptor(*GetTableDescriptor(kvDB, codec, database, table)) 99 } 100 101 // RandDatum generates a random Datum of the given type. 102 // If nullOk is true, the datum can be DNull. 103 // Note that if typ.Family is UNKNOWN, the datum will always be DNull, 104 // regardless of the null flag. 105 func RandDatum(rng *rand.Rand, typ *types.T, nullOk bool) tree.Datum { 106 nullDenominator := 10 107 if !nullOk { 108 nullDenominator = 0 109 } 110 return RandDatumWithNullChance(rng, typ, nullDenominator) 111 } 112 113 // RandDatumWithNullChance generates a random Datum of the given type. 114 // nullChance is the chance of returning null, expressed as a fraction 115 // denominator. For example, a nullChance of 5 means that there's a 1/5 chance 116 // that DNull will be returned. A nullChance of 0 means that DNull will not 117 // be returned. 118 // Note that if typ.Family is UNKNOWN, the datum will always be 119 // DNull, regardless of the null flag. 120 func RandDatumWithNullChance(rng *rand.Rand, typ *types.T, nullChance int) tree.Datum { 121 if nullChance != 0 && rng.Intn(nullChance) == 0 { 122 return tree.DNull 123 } 124 // Sometimes pick from a predetermined list of known interesting datums. 125 if rng.Intn(10) == 0 { 126 if special := randInterestingDatum(rng, typ); special != nil { 127 return special 128 } 129 } 130 switch typ.Family() { 131 case types.BoolFamily: 132 return tree.MakeDBool(rng.Intn(2) == 1) 133 case types.IntFamily: 134 switch typ.Width() { 135 case 64: 136 // int64(rng.Uint64()) to get negative numbers, too 137 return tree.NewDInt(tree.DInt(int64(rng.Uint64()))) 138 case 32: 139 // int32(rng.Uint64()) to get negative numbers, too 140 return tree.NewDInt(tree.DInt(int32(rng.Uint64()))) 141 case 16: 142 // int16(rng.Uint64()) to get negative numbers, too 143 return tree.NewDInt(tree.DInt(int16(rng.Uint64()))) 144 case 8: 145 // int8(rng.Uint64()) to get negative numbers, too 146 return tree.NewDInt(tree.DInt(int8(rng.Uint64()))) 147 default: 148 panic(fmt.Sprintf("int with an unexpected width %d", typ.Width())) 149 } 150 case types.FloatFamily: 151 switch typ.Width() { 152 case 64: 153 return tree.NewDFloat(tree.DFloat(rng.NormFloat64())) 154 case 32: 155 return tree.NewDFloat(tree.DFloat(float32(rng.NormFloat64()))) 156 default: 157 panic(fmt.Sprintf("float with an unexpected width %d", typ.Width())) 158 } 159 case types.GeographyFamily: 160 // TODO(otan): generate fake data properly. 161 return tree.NewDGeography( 162 geo.MustParseGeographyFromEWKBRaw([]byte("\x01\x01\x00\x00\x20\xe6\x10\x00\x00\x00\x00\x00\x00\x00\x00\xf0\x3f\x00\x00\x00\x00\x00\x00\xf0\x3f")), 163 ) 164 case types.GeometryFamily: 165 // TODO(otan): generate fake data properly. 166 return tree.NewDGeometry( 167 geo.MustParseGeometryFromEWKBRaw([]byte("\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0\x3f\x00\x00\x00\x00\x00\x00\xf0\x3f")), 168 ) 169 case types.DecimalFamily: 170 d := &tree.DDecimal{} 171 // int64(rng.Uint64()) to get negative numbers, too 172 d.Decimal.SetFinite(int64(rng.Uint64()), int32(rng.Intn(40)-20)) 173 return d 174 case types.DateFamily: 175 d, err := pgdate.MakeDateFromUnixEpoch(int64(rng.Intn(10000))) 176 if err != nil { 177 return nil 178 } 179 return tree.NewDDate(d) 180 case types.TimeFamily: 181 return tree.MakeDTime(timeofday.Random(rng)).Round(tree.TimeFamilyPrecisionToRoundDuration(typ.Precision())) 182 case types.TimeTZFamily: 183 return tree.NewDTimeTZFromOffset( 184 timeofday.Random(rng), 185 // We cannot randomize seconds, because lib/pq does NOT print the 186 // second offsets making some tests break when comparing 187 // results in == results out using string comparison. 188 (rng.Int31n(28*60+59)-(14*60+59))*60, 189 ).Round(tree.TimeFamilyPrecisionToRoundDuration(typ.Precision())) 190 case types.TimestampFamily: 191 return tree.MustMakeDTimestamp( 192 timeutil.Unix(rng.Int63n(1000000), rng.Int63n(1000000)), 193 tree.TimeFamilyPrecisionToRoundDuration(typ.Precision()), 194 ) 195 case types.IntervalFamily: 196 sign := 1 - rng.Int63n(2)*2 197 return &tree.DInterval{Duration: duration.MakeDuration( 198 sign*rng.Int63n(25*3600*int64(1000000000)), 199 sign*rng.Int63n(1000), 200 sign*rng.Int63n(1000), 201 )} 202 case types.UuidFamily: 203 gen := uuid.NewGenWithReader(rng) 204 return tree.NewDUuid(tree.DUuid{UUID: uuid.Must(gen.NewV4())}) 205 case types.INetFamily: 206 ipAddr := ipaddr.RandIPAddr(rng) 207 return tree.NewDIPAddr(tree.DIPAddr{IPAddr: ipAddr}) 208 case types.JsonFamily: 209 j, err := json.Random(20, rng) 210 if err != nil { 211 return nil 212 } 213 return &tree.DJSON{JSON: j} 214 case types.TupleFamily: 215 tuple := tree.DTuple{D: make(tree.Datums, len(typ.TupleContents()))} 216 for i := range typ.TupleContents() { 217 tuple.D[i] = RandDatum(rng, typ.TupleContents()[i], true) 218 } 219 return &tuple 220 case types.BitFamily: 221 width := typ.Width() 222 if width == 0 { 223 width = rng.Int31n(100) 224 } 225 r := bitarray.Rand(rng, uint(width)) 226 return &tree.DBitArray{BitArray: r} 227 case types.StringFamily: 228 // Generate a random ASCII string. 229 p := make([]byte, rng.Intn(10)) 230 for i := range p { 231 p[i] = byte(1 + rng.Intn(127)) 232 } 233 if typ.Oid() == oid.T_name { 234 return tree.NewDName(string(p)) 235 } 236 return tree.NewDString(string(p)) 237 case types.BytesFamily: 238 p := make([]byte, rng.Intn(10)) 239 _, _ = rng.Read(p) 240 return tree.NewDBytes(tree.DBytes(p)) 241 case types.TimestampTZFamily: 242 return tree.MustMakeDTimestampTZ( 243 timeutil.Unix(rng.Int63n(1000000), rng.Int63n(1000000)), 244 tree.TimeFamilyPrecisionToRoundDuration(typ.Precision()), 245 ) 246 case types.CollatedStringFamily: 247 // Generate a random Unicode string. 248 var buf bytes.Buffer 249 n := rng.Intn(10) 250 for i := 0; i < n; i++ { 251 var r rune 252 for { 253 r = rune(rng.Intn(unicode.MaxRune + 1)) 254 if !unicode.Is(unicode.C, r) { 255 break 256 } 257 } 258 buf.WriteRune(r) 259 } 260 d, err := tree.NewDCollatedString(buf.String(), typ.Locale(), &tree.CollationEnvironment{}) 261 if err != nil { 262 panic(err) 263 } 264 return d 265 case types.OidFamily: 266 return tree.NewDOid(tree.DInt(rng.Uint32())) 267 case types.UnknownFamily: 268 return tree.DNull 269 case types.ArrayFamily: 270 return RandArray(rng, typ, 0) 271 case types.AnyFamily: 272 return RandDatumWithNullChance(rng, RandType(rng), nullChance) 273 case types.EnumFamily: 274 // We don't yet have the ability to generate random user defined types. 275 return tree.DNull 276 default: 277 panic(fmt.Sprintf("invalid type %v", typ.DebugString())) 278 } 279 } 280 281 // RandArray generates a random DArray where the contents have nullChance 282 // of being null. 283 func RandArray(rng *rand.Rand, typ *types.T, nullChance int) tree.Datum { 284 contents := typ.ArrayContents() 285 if contents.Family() == types.AnyFamily { 286 contents = RandArrayContentsType(rng) 287 } 288 arr := tree.NewDArray(contents) 289 for i := 0; i < rng.Intn(10); i++ { 290 if err := arr.Append(RandDatumWithNullChance(rng, contents, nullChance)); err != nil { 291 panic(err) 292 } 293 } 294 return arr 295 } 296 297 const simpleRange = 10 298 299 // RandDatumSimple generates a random Datum of the given type. The generated 300 // datums will be simple (i.e., only one character or an integer between 0 301 // and 9), such that repeated calls to this function will regularly return a 302 // previously generated datum. 303 func RandDatumSimple(rng *rand.Rand, typ *types.T) tree.Datum { 304 datum := tree.DNull 305 switch typ.Family() { 306 case types.BitFamily: 307 datum, _ = tree.NewDBitArrayFromInt(rng.Int63n(simpleRange), uint(bits.Len(simpleRange))) 308 case types.BoolFamily: 309 if rng.Intn(2) == 1 { 310 datum = tree.DBoolTrue 311 } else { 312 datum = tree.DBoolFalse 313 } 314 case types.BytesFamily: 315 datum = tree.NewDBytes(tree.DBytes(randStringSimple(rng))) 316 case types.DateFamily: 317 date, _ := pgdate.MakeDateFromPGEpoch(rng.Int31n(simpleRange)) 318 datum = tree.NewDDate(date) 319 case types.DecimalFamily: 320 datum = &tree.DDecimal{ 321 Decimal: apd.Decimal{ 322 Coeff: *big.NewInt(rng.Int63n(simpleRange)), 323 }, 324 } 325 case types.IntFamily: 326 datum = tree.NewDInt(tree.DInt(rng.Intn(simpleRange))) 327 case types.IntervalFamily: 328 datum = &tree.DInterval{Duration: duration.MakeDuration( 329 rng.Int63n(simpleRange)*1e9, 330 0, 331 0, 332 )} 333 case types.FloatFamily: 334 datum = tree.NewDFloat(tree.DFloat(rng.Intn(simpleRange))) 335 case types.INetFamily: 336 datum = tree.NewDIPAddr(tree.DIPAddr{ 337 IPAddr: ipaddr.IPAddr{ 338 Addr: ipaddr.Addr(uint128.FromInts(0, uint64(rng.Intn(simpleRange)))), 339 }, 340 }) 341 case types.JsonFamily: 342 datum = tree.NewDJSON(randJSONSimple(rng)) 343 case types.OidFamily: 344 datum = tree.NewDOid(tree.DInt(rng.Intn(simpleRange))) 345 case types.StringFamily: 346 datum = tree.NewDString(randStringSimple(rng)) 347 case types.TimeFamily: 348 datum = tree.MakeDTime(timeofday.New(0, rng.Intn(simpleRange), 0, 0)) 349 case types.TimestampFamily: 350 datum = tree.MustMakeDTimestamp(time.Date(2000, 1, 1, rng.Intn(simpleRange), 0, 0, 0, time.UTC), time.Microsecond) 351 case types.TimestampTZFamily: 352 datum = tree.MustMakeDTimestampTZ(time.Date(2000, 1, 1, rng.Intn(simpleRange), 0, 0, 0, time.UTC), time.Microsecond) 353 case types.UuidFamily: 354 datum = tree.NewDUuid(tree.DUuid{ 355 UUID: uuid.FromUint128(uint128.FromInts(0, uint64(rng.Intn(simpleRange)))), 356 }) 357 } 358 return datum 359 } 360 361 func randStringSimple(rng *rand.Rand) string { 362 return string('A' + rng.Intn(simpleRange)) 363 } 364 365 func randJSONSimple(rng *rand.Rand) json.JSON { 366 switch rng.Intn(10) { 367 case 0: 368 return json.NullJSONValue 369 case 1: 370 return json.FalseJSONValue 371 case 2: 372 return json.TrueJSONValue 373 case 3: 374 return json.FromInt(rng.Intn(simpleRange)) 375 case 4: 376 return json.FromString(randStringSimple(rng)) 377 case 5: 378 a := json.NewArrayBuilder(0) 379 for i := rng.Intn(3); i >= 0; i-- { 380 a.Add(randJSONSimple(rng)) 381 } 382 return a.Build() 383 default: 384 a := json.NewObjectBuilder(0) 385 for i := rng.Intn(3); i >= 0; i-- { 386 a.Add(randStringSimple(rng), randJSONSimple(rng)) 387 } 388 return a.Build() 389 } 390 } 391 392 // GenerateRandInterestingTable takes a gosql.DB connection and creates 393 // a table with all the types in randInterestingDatums and rows of the 394 // interesting datums. 395 func GenerateRandInterestingTable(db *gosql.DB, dbName, tableName string) error { 396 var ( 397 randTypes []*types.T 398 colNames []string 399 ) 400 numRows := 0 401 for _, v := range randInterestingDatums { 402 colTyp := v[0].ResolvedType() 403 randTypes = append(randTypes, colTyp) 404 colNames = append(colNames, colTyp.Name()) 405 if len(v) > numRows { 406 numRows = len(v) 407 } 408 } 409 410 var columns strings.Builder 411 comma := "" 412 for i, typ := range randTypes { 413 columns.WriteString(comma) 414 columns.WriteString(colNames[i]) 415 columns.WriteString(" ") 416 columns.WriteString(typ.SQLString()) 417 comma = ", " 418 } 419 420 createStatement := fmt.Sprintf("CREATE TABLE %s.%s (%s)", dbName, tableName, columns.String()) 421 if _, err := db.Exec(createStatement); err != nil { 422 return err 423 } 424 425 row := make([]string, len(randTypes)) 426 for i := 0; i < numRows; i++ { 427 for j, typ := range randTypes { 428 datums := randInterestingDatums[typ.Family()] 429 var d tree.Datum 430 if i < len(datums) { 431 d = datums[i] 432 } else { 433 d = tree.DNull 434 } 435 row[j] = tree.AsStringWithFlags(d, tree.FmtParsable) 436 } 437 var builder strings.Builder 438 comma := "" 439 for _, d := range row { 440 builder.WriteString(comma) 441 builder.WriteString(d) 442 comma = ", " 443 } 444 insertStmt := fmt.Sprintf("INSERT INTO %s.%s VALUES (%s)", dbName, tableName, builder.String()) 445 if _, err := db.Exec(insertStmt); err != nil { 446 return err 447 } 448 } 449 return nil 450 } 451 452 var ( 453 // randInterestingDatums is a collection of interesting datums that can be 454 // used for random testing. 455 randInterestingDatums = map[types.Family][]tree.Datum{ 456 types.BoolFamily: { 457 tree.DBoolTrue, 458 tree.DBoolFalse, 459 }, 460 types.IntFamily: { 461 tree.NewDInt(tree.DInt(0)), 462 tree.NewDInt(tree.DInt(-1)), 463 tree.NewDInt(tree.DInt(1)), 464 tree.NewDInt(tree.DInt(math.MaxInt8)), 465 tree.NewDInt(tree.DInt(math.MinInt8)), 466 tree.NewDInt(tree.DInt(math.MaxInt16)), 467 tree.NewDInt(tree.DInt(math.MinInt16)), 468 tree.NewDInt(tree.DInt(math.MaxInt32)), 469 tree.NewDInt(tree.DInt(math.MinInt32)), 470 tree.NewDInt(tree.DInt(math.MaxInt64)), 471 // Use +1 because that's the SQL range. 472 tree.NewDInt(tree.DInt(math.MinInt64 + 1)), 473 }, 474 types.FloatFamily: { 475 tree.NewDFloat(tree.DFloat(0)), 476 tree.NewDFloat(tree.DFloat(1)), 477 tree.NewDFloat(tree.DFloat(-1)), 478 tree.NewDFloat(tree.DFloat(math.SmallestNonzeroFloat32)), 479 tree.NewDFloat(tree.DFloat(math.MaxFloat32)), 480 tree.NewDFloat(tree.DFloat(math.SmallestNonzeroFloat64)), 481 tree.NewDFloat(tree.DFloat(math.MaxFloat64)), 482 tree.NewDFloat(tree.DFloat(math.Inf(1))), 483 tree.NewDFloat(tree.DFloat(math.Inf(-1))), 484 tree.NewDFloat(tree.DFloat(math.NaN())), 485 }, 486 types.DecimalFamily: func() []tree.Datum { 487 var res []tree.Datum 488 for _, s := range []string{ 489 "0", 490 "1", 491 "-1", 492 "Inf", 493 "-Inf", 494 "NaN", 495 "-12.34e400", 496 } { 497 d, err := tree.ParseDDecimal(s) 498 if err != nil { 499 panic(err) 500 } 501 res = append(res, d) 502 } 503 return res 504 }(), 505 types.DateFamily: { 506 tree.NewDDate(pgdate.MakeCompatibleDateFromDisk(0)), 507 tree.NewDDate(pgdate.LowDate), 508 tree.NewDDate(pgdate.HighDate), 509 tree.NewDDate(pgdate.PosInfDate), 510 tree.NewDDate(pgdate.NegInfDate), 511 }, 512 types.TimeFamily: { 513 tree.MakeDTime(timeofday.Min), 514 tree.MakeDTime(timeofday.Max), 515 tree.MakeDTime(timeofday.Time2400), 516 }, 517 types.TimeTZFamily: { 518 tree.DMinTimeTZ, 519 tree.DMaxTimeTZ, 520 }, 521 types.TimestampFamily: func() []tree.Datum { 522 res := make([]tree.Datum, len(randTimestampSpecials)) 523 for i, t := range randTimestampSpecials { 524 res[i] = tree.MustMakeDTimestamp(t, time.Microsecond) 525 } 526 return res 527 }(), 528 types.TimestampTZFamily: func() []tree.Datum { 529 res := make([]tree.Datum, len(randTimestampSpecials)) 530 for i, t := range randTimestampSpecials { 531 res[i] = tree.MustMakeDTimestampTZ(t, time.Microsecond) 532 } 533 return res 534 }(), 535 types.IntervalFamily: { 536 &tree.DInterval{Duration: duration.MakeDuration(0, 0, 0)}, 537 &tree.DInterval{Duration: duration.MakeDuration(0, 1, 0)}, 538 &tree.DInterval{Duration: duration.MakeDuration(1, 0, 0)}, 539 &tree.DInterval{Duration: duration.MakeDuration(1, 1, 1)}, 540 // TODO(mjibson): fix intervals to stop overflowing then this can be larger. 541 &tree.DInterval{Duration: duration.MakeDuration(0, 0, 290*12)}, 542 }, 543 types.GeographyFamily: { 544 // NOTE(otan): we cannot use WKT here because roachtests do not have geos uploaded. 545 // If we parse WKT ourselves or upload GEOS on every roachtest, we may be able to avoid this. 546 // POINT(1.0 1.0) 547 &tree.DGeography{Geography: geo.MustParseGeography("0101000000000000000000F03F000000000000F03F")}, 548 // LINESTRING(1.0 1.0, 2.0 2.0) 549 &tree.DGeography{Geography: geo.MustParseGeography("010200000002000000000000000000F03F000000000000F03F00000000000000400000000000000040")}, 550 // POLYGON((0.0 0.0, 1.0 0.0, 1.0 1.0, 0.0 1.0, 0.0 0.0)) 551 &tree.DGeography{Geography: geo.MustParseGeography("0103000000010000000500000000000000000000000000000000000000000000000000F03F0000000000000000000000000000F03F000000000000F03F0000000000000000000000000000F03F00000000000000000000000000000000")}, 552 // POLYGON((0.0 0.0, 1.0 0.0, 1.0 1.0, 0.0 1.0, 0.0 0.0), (0.2 0.2, 0.2 0.4, 0.4 0.4, 0.4 0.2, 0.2 0.2)) 553 &tree.DGeography{Geography: geo.MustParseGeography("0103000000020000000500000000000000000000000000000000000000000000000000F03F0000000000000000000000000000F03F000000000000F03F0000000000000000000000000000F03F00000000000000000000000000000000050000009A9999999999C93F9A9999999999C93F9A9999999999C93F9A9999999999D93F9A9999999999D93F9A9999999999D93F9A9999999999D93F9A9999999999C93F9A9999999999C93F9A9999999999C93F")}, 554 // MULTIPOINT ((10 40), (40 30), (20 20), (30 10)) 555 &tree.DGeography{Geography: geo.MustParseGeography("010400000004000000010100000000000000000024400000000000004440010100000000000000000044400000000000003E4001010000000000000000003440000000000000344001010000000000000000003E400000000000002440")}, 556 // MULTILINESTRING ((10 10, 20 20, 10 40), (40 40, 30 30, 40 20, 30 10)) 557 &tree.DGeography{Geography: geo.MustParseGeography("010500000002000000010200000003000000000000000000244000000000000024400000000000003440000000000000344000000000000024400000000000004440010200000004000000000000000000444000000000000044400000000000003E400000000000003E40000000000000444000000000000034400000000000003E400000000000002440")}, 558 // MULTIPOLYGON (((40 40, 20 45, 45 30, 40 40)),((20 35, 10 30, 10 10, 30 5, 45 20, 20 35),(30 20, 20 15, 20 25, 30 20))) 559 &tree.DGeography{Geography: geo.MustParseGeography("01060000000200000001030000000100000004000000000000000000444000000000000044400000000000003440000000000080464000000000008046400000000000003E4000000000000044400000000000004440010300000002000000060000000000000000003440000000000080414000000000000024400000000000003E40000000000000244000000000000024400000000000003E4000000000000014400000000000804640000000000000344000000000000034400000000000804140040000000000000000003E40000000000000344000000000000034400000000000002E40000000000000344000000000000039400000000000003E400000000000003440")}, 560 // GEOMETRYCOLLECTION (POINT (40 10),LINESTRING (10 10, 20 20, 10 40),POLYGON ((40 40, 20 45, 45 30, 40 40))) 561 &tree.DGeography{Geography: geo.MustParseGeography("01070000000300000001010000000000000000004440000000000000244001020000000300000000000000000024400000000000002440000000000000344000000000000034400000000000002440000000000000444001030000000100000004000000000000000000444000000000000044400000000000003440000000000080464000000000008046400000000000003E4000000000000044400000000000004440")}, 562 // POINT EMPTY 563 &tree.DGeography{Geography: geo.MustParseGeography("0101000000000000000000F87F000000000000F87F")}, 564 // LINESTRING EMPTY 565 &tree.DGeography{Geography: geo.MustParseGeography("010200000000000000")}, 566 // POLYGON EMPTY 567 &tree.DGeography{Geography: geo.MustParseGeography("010300000000000000")}, 568 // MULTIPOINT EMPTY 569 &tree.DGeography{Geography: geo.MustParseGeography("010400000000000000")}, 570 // MULTILINESTRING EMPTY 571 &tree.DGeography{Geography: geo.MustParseGeography("010500000000000000")}, 572 // MULTIPOLYGON EMPTY 573 &tree.DGeography{Geography: geo.MustParseGeography("010600000000000000")}, 574 // GEOMETRYCOLLECTION EMPTY 575 &tree.DGeography{Geography: geo.MustParseGeography("010700000000000000")}, 576 }, 577 types.GeometryFamily: { 578 // NOTE(otan): we cannot use WKT here because roachtests do not have geos uploaded. 579 // If we parse WKT ourselves or upload GEOS on every roachtest, we may be able to avoid this. 580 // POINT(1.0 1.0) 581 &tree.DGeometry{Geometry: geo.MustParseGeometry("0101000000000000000000F03F000000000000F03F")}, 582 // LINESTRING(1.0 1.0, 2.0 2.0) 583 &tree.DGeometry{Geometry: geo.MustParseGeometry("010200000002000000000000000000F03F000000000000F03F00000000000000400000000000000040")}, 584 // POLYGON((0.0 0.0, 1.0 0.0, 1.0 1.0, 0.0 1.0, 0.0 0.0)) 585 &tree.DGeometry{Geometry: geo.MustParseGeometry("0103000000010000000500000000000000000000000000000000000000000000000000F03F0000000000000000000000000000F03F000000000000F03F0000000000000000000000000000F03F00000000000000000000000000000000")}, 586 // POLYGON((0.0 0.0, 1.0 0.0, 1.0 1.0, 0.0 1.0, 0.0 0.0), (0.2 0.2, 0.2 0.4, 0.4 0.4, 0.4 0.2, 0.2 0.2)) 587 &tree.DGeometry{Geometry: geo.MustParseGeometry("0103000000020000000500000000000000000000000000000000000000000000000000F03F0000000000000000000000000000F03F000000000000F03F0000000000000000000000000000F03F00000000000000000000000000000000050000009A9999999999C93F9A9999999999C93F9A9999999999C93F9A9999999999D93F9A9999999999D93F9A9999999999D93F9A9999999999D93F9A9999999999C93F9A9999999999C93F9A9999999999C93F")}, 588 // MULTIPOINT ((10 40), (40 30), (20 20), (30 10)) 589 &tree.DGeometry{Geometry: geo.MustParseGeometry("010400000004000000010100000000000000000024400000000000004440010100000000000000000044400000000000003E4001010000000000000000003440000000000000344001010000000000000000003E400000000000002440")}, 590 // MULTILINESTRING ((10 10, 20 20, 10 40), (40 40, 30 30, 40 20, 30 10)) 591 &tree.DGeometry{Geometry: geo.MustParseGeometry("010500000002000000010200000003000000000000000000244000000000000024400000000000003440000000000000344000000000000024400000000000004440010200000004000000000000000000444000000000000044400000000000003E400000000000003E40000000000000444000000000000034400000000000003E400000000000002440")}, 592 // MULTIPOLYGON (((40 40, 20 45, 45 30, 40 40)),((20 35, 10 30, 10 10, 30 5, 45 20, 20 35),(30 20, 20 15, 20 25, 30 20))) 593 &tree.DGeometry{Geometry: geo.MustParseGeometry("01060000000200000001030000000100000004000000000000000000444000000000000044400000000000003440000000000080464000000000008046400000000000003E4000000000000044400000000000004440010300000002000000060000000000000000003440000000000080414000000000000024400000000000003E40000000000000244000000000000024400000000000003E4000000000000014400000000000804640000000000000344000000000000034400000000000804140040000000000000000003E40000000000000344000000000000034400000000000002E40000000000000344000000000000039400000000000003E400000000000003440")}, 594 // GEOMETRYCOLLECTION (POINT (40 10),LINESTRING (10 10, 20 20, 10 40),POLYGON ((40 40, 20 45, 45 30, 40 40))) 595 &tree.DGeometry{Geometry: geo.MustParseGeometry("01070000000300000001010000000000000000004440000000000000244001020000000300000000000000000024400000000000002440000000000000344000000000000034400000000000002440000000000000444001030000000100000004000000000000000000444000000000000044400000000000003440000000000080464000000000008046400000000000003E4000000000000044400000000000004440")}, 596 // POINT EMPTY 597 &tree.DGeometry{Geometry: geo.MustParseGeometry("0101000000000000000000F87F000000000000F87F")}, 598 // LINESTRING EMPTY 599 &tree.DGeometry{Geometry: geo.MustParseGeometry("010200000000000000")}, 600 // POLYGON EMPTY 601 &tree.DGeometry{Geometry: geo.MustParseGeometry("010300000000000000")}, 602 // MULTIPOINT EMPTY 603 &tree.DGeometry{Geometry: geo.MustParseGeometry("010400000000000000")}, 604 // MULTILINESTRING EMPTY 605 &tree.DGeometry{Geometry: geo.MustParseGeometry("010500000000000000")}, 606 // MULTIPOLYGON EMPTY 607 &tree.DGeometry{Geometry: geo.MustParseGeometry("010600000000000000")}, 608 // GEOMETRYCOLLECTION EMPTY 609 &tree.DGeometry{Geometry: geo.MustParseGeometry("010700000000000000")}, 610 }, 611 types.StringFamily: { 612 tree.NewDString(""), 613 tree.NewDString("X"), 614 tree.NewDString(`"`), 615 tree.NewDString(`'`), 616 tree.NewDString("\x00"), 617 tree.NewDString("\u2603"), // unicode snowman 618 }, 619 types.BytesFamily: { 620 tree.NewDBytes(""), 621 tree.NewDBytes("X"), 622 tree.NewDBytes(`"`), 623 tree.NewDBytes(`'`), 624 tree.NewDBytes("\x00"), 625 tree.NewDBytes("\u2603"), // unicode snowman 626 tree.NewDBytes("\xFF"), // invalid utf-8 sequence, but a valid bytes 627 }, 628 types.OidFamily: { 629 tree.NewDOid(0), 630 }, 631 types.UuidFamily: { 632 tree.DMinUUID, 633 tree.DMaxUUID, 634 }, 635 types.INetFamily: { 636 tree.DMinIPAddr, 637 tree.DMaxIPAddr, 638 }, 639 types.JsonFamily: func() []tree.Datum { 640 var res []tree.Datum 641 for _, s := range []string{ 642 `{}`, 643 `1`, 644 `{"test": "json"}`, 645 } { 646 d, err := tree.ParseDJSON(s) 647 if err != nil { 648 panic(err) 649 } 650 res = append(res, d) 651 } 652 return res 653 }(), 654 types.BitFamily: func() []tree.Datum { 655 var res []tree.Datum 656 for _, i := range []int64{ 657 0, 658 1<<63 - 1, 659 } { 660 d, err := tree.NewDBitArrayFromInt(i, 64) 661 if err != nil { 662 panic(err) 663 } 664 res = append(res, d) 665 } 666 return res 667 }(), 668 } 669 randTimestampSpecials = []time.Time{ 670 {}, 671 time.Date(-2000, time.January, 1, 0, 0, 0, 0, time.UTC), 672 time.Date(3000, time.January, 1, 0, 0, 0, 0, time.UTC), 673 // NOTE(otan): we cannot support this as it does not work with colexec in tests. 674 tree.MinSupportedTime, 675 tree.MaxSupportedTime, 676 } 677 ) 678 679 var ( 680 // seedTypes includes the following types that form the basis of randomly 681 // generated types: 682 // - All scalar types, except UNKNOWN and ANY 683 // - ARRAY of ANY, where the ANY will be replaced with one of the legal 684 // array element types in RandType 685 // - OIDVECTOR and INT2VECTOR types 686 seedTypes []*types.T 687 688 // arrayContentsTypes contains all of the types that are valid to store within 689 // an array. 690 arrayContentsTypes []*types.T 691 collationLocales = [...]string{"da", "de", "en"} 692 ) 693 694 func init() { 695 for _, typ := range types.OidToType { 696 switch typ.Oid() { 697 case oid.T_unknown, oid.T_anyelement: 698 // Don't include these. 699 case oid.T_anyarray, oid.T_oidvector, oid.T_int2vector: 700 // Include these. 701 seedTypes = append(seedTypes, typ) 702 default: 703 // Only include scalar types. 704 if typ.Family() != types.ArrayFamily { 705 seedTypes = append(seedTypes, typ) 706 } 707 } 708 } 709 710 for _, typ := range types.OidToType { 711 // Don't include un-encodable types. 712 encTyp, err := datumTypeToArrayElementEncodingType(typ) 713 if err != nil || encTyp == 0 { 714 continue 715 } 716 717 // Don't include reg types, since parser currently doesn't allow them to 718 // be declared as array element types. 719 if typ.Family() == types.OidFamily && typ.Oid() != oid.T_oid { 720 continue 721 } 722 723 arrayContentsTypes = append(arrayContentsTypes, typ) 724 } 725 726 // Sort these so randomly chosen indexes always point to the same element. 727 sort.Slice(seedTypes, func(i, j int) bool { 728 return seedTypes[i].String() < seedTypes[j].String() 729 }) 730 sort.Slice(arrayContentsTypes, func(i, j int) bool { 731 return arrayContentsTypes[i].String() < arrayContentsTypes[j].String() 732 }) 733 } 734 735 // randInterestingDatum returns an interesting Datum of type typ. 736 // If there are no such Datums for a scalar type, it panics. Otherwise, 737 // it returns nil if there are no such Datums. Note that it pays attention 738 // to the width of the requested type for Int and Float type families. 739 func randInterestingDatum(rng *rand.Rand, typ *types.T) tree.Datum { 740 specials, ok := randInterestingDatums[typ.Family()] 741 if !ok || len(specials) == 0 { 742 for _, sc := range types.Scalar { 743 // Panic if a scalar type doesn't have an interesting datum. 744 if sc == typ { 745 panic(fmt.Sprintf("no interesting datum for type %s found", typ.String())) 746 } 747 } 748 return nil 749 } 750 751 special := specials[rng.Intn(len(specials))] 752 switch typ.Family() { 753 case types.IntFamily: 754 switch typ.Width() { 755 case 64: 756 return special 757 case 32: 758 return tree.NewDInt(tree.DInt(int32(tree.MustBeDInt(special)))) 759 case 16: 760 return tree.NewDInt(tree.DInt(int16(tree.MustBeDInt(special)))) 761 case 8: 762 return tree.NewDInt(tree.DInt(int8(tree.MustBeDInt(special)))) 763 default: 764 panic(fmt.Sprintf("int with an unexpected width %d", typ.Width())) 765 } 766 case types.FloatFamily: 767 switch typ.Width() { 768 case 64: 769 return special 770 case 32: 771 return tree.NewDFloat(tree.DFloat(float32(*special.(*tree.DFloat)))) 772 default: 773 panic(fmt.Sprintf("float with an unexpected width %d", typ.Width())) 774 } 775 default: 776 return special 777 } 778 } 779 780 // RandCollationLocale returns a random element of collationLocales. 781 func RandCollationLocale(rng *rand.Rand) *string { 782 return &collationLocales[rng.Intn(len(collationLocales))] 783 } 784 785 // RandType returns a random type value. 786 func RandType(rng *rand.Rand) *types.T { 787 return randType(rng, seedTypes) 788 } 789 790 // RandScalarType returns a random type value that is not an array or tuple. 791 func RandScalarType(rng *rand.Rand) *types.T { 792 return randType(rng, types.Scalar) 793 } 794 795 // RandArrayContentsType returns a random type that's guaranteed to be valid to 796 // use as the contents of an array. 797 func RandArrayContentsType(rng *rand.Rand) *types.T { 798 return randType(rng, arrayContentsTypes) 799 } 800 801 func randType(rng *rand.Rand, typs []*types.T) *types.T { 802 typ := typs[rng.Intn(len(typs))] 803 switch typ.Family() { 804 case types.BitFamily: 805 return types.MakeBit(int32(rng.Intn(50))) 806 case types.CollatedStringFamily: 807 return types.MakeCollatedString(types.String, *RandCollationLocale(rng)) 808 case types.ArrayFamily: 809 if typ.ArrayContents().Family() == types.AnyFamily { 810 inner := RandArrayContentsType(rng) 811 if inner.Family() == types.CollatedStringFamily { 812 // TODO(justin): change this when collated arrays are supported. 813 inner = types.String 814 } 815 return types.MakeArray(inner) 816 } 817 case types.TupleFamily: 818 // Generate tuples between 0 and 4 datums in length 819 len := rng.Intn(5) 820 contents := make([]*types.T, len) 821 for i := range contents { 822 contents[i] = RandType(rng) 823 } 824 return types.MakeTuple(contents) 825 } 826 return typ 827 } 828 829 // RandColumnType returns a random type that is a legal column type (e.g. no 830 // nested arrays or tuples). 831 func RandColumnType(rng *rand.Rand) *types.T { 832 for { 833 typ := RandType(rng) 834 if err := ValidateColumnDefType(typ); err == nil { 835 return typ 836 } 837 } 838 } 839 840 // RandArrayType generates a random array type. 841 func RandArrayType(rng *rand.Rand) *types.T { 842 for { 843 typ := RandColumnType(rng) 844 resTyp := types.MakeArray(typ) 845 if err := ValidateColumnDefType(resTyp); err == nil { 846 return resTyp 847 } 848 } 849 } 850 851 // RandColumnTypes returns a slice of numCols random types. These types must be 852 // legal table column types. 853 func RandColumnTypes(rng *rand.Rand, numCols int) []*types.T { 854 types := make([]*types.T, numCols) 855 for i := range types { 856 types[i] = RandColumnType(rng) 857 } 858 return types 859 } 860 861 // RandSortingType returns a column type which can be key-encoded. 862 func RandSortingType(rng *rand.Rand) *types.T { 863 typ := RandType(rng) 864 for MustBeValueEncoded(typ) { 865 typ = RandType(rng) 866 } 867 return typ 868 } 869 870 // RandSortingTypes returns a slice of numCols random ColumnType values 871 // which are key-encodable. 872 func RandSortingTypes(rng *rand.Rand, numCols int) []*types.T { 873 types := make([]*types.T, numCols) 874 for i := range types { 875 types[i] = RandSortingType(rng) 876 } 877 return types 878 } 879 880 // RandDatumEncoding returns a random DatumEncoding value. 881 func RandDatumEncoding(rng *rand.Rand) DatumEncoding { 882 return DatumEncoding(rng.Intn(len(DatumEncoding_value))) 883 } 884 885 // RandEncodableType wraps RandType in order to workaround #36736, which fails 886 // when name[] (or other type using DTypeWrapper) is encoded. 887 // 888 // TODO(andyk): Remove this workaround once #36736 is resolved. Also, RandDatum 889 // really should be extended to create DTypeWrapper datums with alternate OIDs 890 // like oid.T_varchar for better testing. 891 func RandEncodableType(rng *rand.Rand) *types.T { 892 var isEncodableType func(t *types.T) bool 893 isEncodableType = func(t *types.T) bool { 894 switch t.Family() { 895 case types.ArrayFamily: 896 // Due to #36736, any type returned by RandType that gets turned into 897 // a DTypeWrapper random datum will not work. Currently, that's just 898 // types.Name. 899 if t.ArrayContents().Oid() == oid.T_name { 900 return false 901 } 902 return isEncodableType(t.ArrayContents()) 903 904 case types.TupleFamily: 905 for i := range t.TupleContents() { 906 if !isEncodableType(t.TupleContents()[i]) { 907 return false 908 } 909 } 910 } 911 return true 912 } 913 914 for { 915 typ := RandType(rng) 916 if isEncodableType(typ) { 917 return typ 918 } 919 } 920 } 921 922 // RandEncodableColumnTypes works around #36736, which fails when name[] (or 923 // other type using DTypeWrapper) is encoded. 924 // 925 // TODO(andyk): Remove this workaround once #36736 is resolved. Replace calls to 926 // it with calls to RandColumnTypes. 927 func RandEncodableColumnTypes(rng *rand.Rand, numCols int) []*types.T { 928 types := make([]*types.T, numCols) 929 for i := range types { 930 for { 931 types[i] = RandEncodableType(rng) 932 if err := ValidateColumnDefType(types[i]); err == nil { 933 break 934 } 935 } 936 } 937 return types 938 } 939 940 // RandEncDatum generates a random EncDatum (of a random type). 941 func RandEncDatum(rng *rand.Rand) (EncDatum, *types.T) { 942 typ := RandEncodableType(rng) 943 datum := RandDatum(rng, typ, true /* nullOk */) 944 return DatumToEncDatum(typ, datum), typ 945 } 946 947 // RandSortingEncDatumSlice generates a slice of random EncDatum values of the 948 // same random type which is key-encodable. 949 func RandSortingEncDatumSlice(rng *rand.Rand, numVals int) ([]EncDatum, *types.T) { 950 typ := RandSortingType(rng) 951 vals := make([]EncDatum, numVals) 952 for i := range vals { 953 vals[i] = DatumToEncDatum(typ, RandDatum(rng, typ, true)) 954 } 955 return vals, typ 956 } 957 958 // RandSortingEncDatumSlices generates EncDatum slices, each slice with values of the same 959 // random type which is key-encodable. 960 func RandSortingEncDatumSlices( 961 rng *rand.Rand, numSets, numValsPerSet int, 962 ) ([][]EncDatum, []*types.T) { 963 vals := make([][]EncDatum, numSets) 964 types := make([]*types.T, numSets) 965 for i := range vals { 966 val, typ := RandSortingEncDatumSlice(rng, numValsPerSet) 967 vals[i], types[i] = val, typ 968 } 969 return vals, types 970 } 971 972 // RandEncDatumRowOfTypes generates a slice of random EncDatum values for the 973 // corresponding type in types. 974 func RandEncDatumRowOfTypes(rng *rand.Rand, types []*types.T) EncDatumRow { 975 vals := make([]EncDatum, len(types)) 976 for i := range types { 977 vals[i] = DatumToEncDatum(types[i], RandDatum(rng, types[i], true)) 978 } 979 return vals 980 } 981 982 // RandEncDatumRows generates EncDatumRows where all rows follow the same random 983 // []ColumnType structure. 984 func RandEncDatumRows(rng *rand.Rand, numRows, numCols int) (EncDatumRows, []*types.T) { 985 types := RandEncodableColumnTypes(rng, numCols) 986 return RandEncDatumRowsOfTypes(rng, numRows, types), types 987 } 988 989 // RandEncDatumRowsOfTypes generates EncDatumRows, each row with values of the 990 // corresponding type in types. 991 func RandEncDatumRowsOfTypes(rng *rand.Rand, numRows int, types []*types.T) EncDatumRows { 992 vals := make(EncDatumRows, numRows) 993 for i := range vals { 994 vals[i] = RandEncDatumRowOfTypes(rng, types) 995 } 996 return vals 997 } 998 999 // TestingMakePrimaryIndexKey creates a key prefix that corresponds to 1000 // a table row (in the primary index); it is intended for tests. 1001 // 1002 // It is exported because it is used by tests outside of this package. 1003 // 1004 // The value types must match the primary key columns (or a prefix of them); 1005 // supported types are: - Datum 1006 // - bool (converts to DBool) 1007 // - int (converts to DInt) 1008 // - string (converts to DString) 1009 func TestingMakePrimaryIndexKey(desc *TableDescriptor, vals ...interface{}) (roachpb.Key, error) { 1010 index := &desc.PrimaryIndex 1011 if len(vals) > len(index.ColumnIDs) { 1012 return nil, errors.Errorf("got %d values, PK has %d columns", len(vals), len(index.ColumnIDs)) 1013 } 1014 datums := make([]tree.Datum, len(vals)) 1015 for i, v := range vals { 1016 switch v := v.(type) { 1017 case bool: 1018 datums[i] = tree.MakeDBool(tree.DBool(v)) 1019 case int: 1020 datums[i] = tree.NewDInt(tree.DInt(v)) 1021 case string: 1022 datums[i] = tree.NewDString(v) 1023 case tree.Datum: 1024 datums[i] = v 1025 default: 1026 return nil, errors.Errorf("unexpected value type %T", v) 1027 } 1028 // Check that the value type matches. 1029 colID := index.ColumnIDs[i] 1030 for i := range desc.Columns { 1031 c := &desc.Columns[i] 1032 if c.ID == colID { 1033 colTyp := datums[i].ResolvedType() 1034 if t := colTyp.Family(); t != c.Type.Family() { 1035 return nil, errors.Errorf("column %d of type %s, got value of type %s", i, c.Type.Family(), t) 1036 } 1037 break 1038 } 1039 } 1040 } 1041 // Create the ColumnID to index in datums slice map needed by 1042 // MakeIndexKeyPrefix. 1043 colIDToRowIndex := make(map[ColumnID]int) 1044 for i := range vals { 1045 colIDToRowIndex[index.ColumnIDs[i]] = i 1046 } 1047 1048 keyPrefix := MakeIndexKeyPrefix(keys.SystemSQLCodec, desc, index.ID) 1049 key, _, err := EncodeIndexKey(desc, index, colIDToRowIndex, datums, keyPrefix) 1050 if err != nil { 1051 return nil, err 1052 } 1053 return roachpb.Key(key), nil 1054 } 1055 1056 // Mutator defines a method that can mutate or add SQL statements. See the 1057 // sql/mutations package. This interface is defined here to avoid cyclic 1058 // dependencies. 1059 type Mutator interface { 1060 Mutate(rng *rand.Rand, stmts []tree.Statement) (mutated []tree.Statement, changed bool) 1061 } 1062 1063 // RandCreateTables creates random table definitions. 1064 func RandCreateTables( 1065 rng *rand.Rand, prefix string, num int, mutators ...Mutator, 1066 ) []tree.Statement { 1067 if num < 1 { 1068 panic("at least one table required") 1069 } 1070 1071 // Make some random tables. 1072 tables := make([]tree.Statement, num) 1073 for i := 0; i < num; i++ { 1074 var interleave *tree.CreateTable 1075 // 50% chance of interleaving past the first table. Interleaving doesn't 1076 // make anything harder to do for tests - so prefer to do it a lot. 1077 if i > 0 && rng.Intn(2) == 0 { 1078 interleave = tables[rng.Intn(i)].(*tree.CreateTable) 1079 } 1080 t := RandCreateTableWithInterleave(rng, prefix, i+1, interleave) 1081 tables[i] = t 1082 } 1083 1084 for _, m := range mutators { 1085 tables, _ = m.Mutate(rng, tables) 1086 } 1087 1088 return tables 1089 } 1090 1091 // RandCreateTable creates a random CreateTable definition. 1092 func RandCreateTable(rng *rand.Rand, prefix string, tableIdx int) *tree.CreateTable { 1093 return RandCreateTableWithInterleave(rng, prefix, tableIdx, nil) 1094 } 1095 1096 // RandCreateTableWithInterleave creates a random CreateTable definition, 1097 // interleaved into the given other CreateTable definition. 1098 func RandCreateTableWithInterleave( 1099 rng *rand.Rand, prefix string, tableIdx int, interleaveInto *tree.CreateTable, 1100 ) *tree.CreateTable { 1101 // columnDefs contains the list of Columns we'll add to our table. 1102 nColumns := randutil.RandIntInRange(rng, 1, 20) 1103 columnDefs := make([]*tree.ColumnTableDef, 0, nColumns) 1104 // defs contains the list of Columns and other attributes (indexes, column 1105 // families, etc) we'll add to our table. 1106 defs := make(tree.TableDefs, 0, len(columnDefs)) 1107 1108 // Find columnDefs from previous create table. 1109 interleaveIntoColumnDefs := make(map[tree.Name]*tree.ColumnTableDef) 1110 var interleaveIntoPK *tree.UniqueConstraintTableDef 1111 if interleaveInto != nil { 1112 for i := range interleaveInto.Defs { 1113 switch d := interleaveInto.Defs[i].(type) { 1114 case *tree.ColumnTableDef: 1115 interleaveIntoColumnDefs[d.Name] = d 1116 case *tree.UniqueConstraintTableDef: 1117 if d.PrimaryKey { 1118 interleaveIntoPK = d 1119 } 1120 } 1121 } 1122 } 1123 var interleaveDef *tree.InterleaveDef 1124 if interleaveIntoPK != nil && len(interleaveIntoPK.Columns) > 0 { 1125 // Make the interleave prefix, which has to be exactly the columns in the 1126 // parent's primary index. 1127 prefixLength := len(interleaveIntoPK.Columns) 1128 fields := make(tree.NameList, prefixLength) 1129 for i := range interleaveIntoPK.Columns[:prefixLength] { 1130 def := interleaveIntoColumnDefs[interleaveIntoPK.Columns[i].Column] 1131 columnDefs = append(columnDefs, def) 1132 defs = append(defs, def) 1133 fields[i] = def.Name 1134 } 1135 1136 extraCols := make([]*tree.ColumnTableDef, nColumns) 1137 // Add more columns to the table. 1138 for i := range extraCols { 1139 extraCol := randColumnTableDef(rng, tableIdx, i+prefixLength) 1140 extraCols[i] = extraCol 1141 columnDefs = append(columnDefs, extraCol) 1142 defs = append(defs, extraCol) 1143 } 1144 1145 rng.Shuffle(nColumns, func(i, j int) { 1146 extraCols[i], extraCols[j] = extraCols[j], extraCols[i] 1147 }) 1148 1149 // Create the primary key to interleave, maybe add some new columns to the 1150 // one we're interleaving. 1151 pk := &tree.UniqueConstraintTableDef{ 1152 PrimaryKey: true, 1153 IndexTableDef: tree.IndexTableDef{ 1154 Columns: interleaveIntoPK.Columns[:prefixLength:prefixLength], 1155 }, 1156 } 1157 for i := range extraCols[:rng.Intn(len(extraCols))] { 1158 pk.Columns = append(pk.Columns, tree.IndexElem{ 1159 Column: extraCols[i].Name, 1160 Direction: tree.Direction(rng.Intn(int(tree.Descending) + 1)), 1161 }) 1162 } 1163 defs = append(defs, pk) 1164 interleaveDef = &tree.InterleaveDef{ 1165 Parent: interleaveInto.Table, 1166 Fields: fields, 1167 } 1168 } else { 1169 // Make new defs from scratch. 1170 for i := 0; i < nColumns; i++ { 1171 columnDef := randColumnTableDef(rng, tableIdx, i) 1172 columnDefs = append(columnDefs, columnDef) 1173 defs = append(defs, columnDef) 1174 } 1175 1176 // Make a random primary key with high likelihood. 1177 if rng.Intn(8) != 0 { 1178 indexDef := randIndexTableDefFromCols(rng, columnDefs) 1179 if len(indexDef.Columns) > 0 { 1180 defs = append(defs, &tree.UniqueConstraintTableDef{ 1181 PrimaryKey: true, 1182 IndexTableDef: indexDef, 1183 }) 1184 } 1185 // Although not necessary for Cockroach to function correctly, 1186 // but for ease of use for any code that introspects on the 1187 // AST data structure (instead of the descriptor which doesn't 1188 // exist yet), explicitly set all PK cols as NOT NULL. 1189 for _, col := range columnDefs { 1190 for _, elem := range indexDef.Columns { 1191 if col.Name == elem.Column { 1192 col.Nullable.Nullability = tree.NotNull 1193 } 1194 } 1195 } 1196 } 1197 } 1198 1199 // Make indexes. 1200 nIdxs := rng.Intn(10) 1201 for i := 0; i < nIdxs; i++ { 1202 indexDef := randIndexTableDefFromCols(rng, columnDefs) 1203 if len(indexDef.Columns) == 0 { 1204 continue 1205 } 1206 unique := rng.Intn(2) == 0 1207 if unique { 1208 defs = append(defs, &tree.UniqueConstraintTableDef{ 1209 IndexTableDef: indexDef, 1210 }) 1211 } else { 1212 defs = append(defs, &indexDef) 1213 } 1214 } 1215 1216 ret := &tree.CreateTable{ 1217 Table: tree.MakeUnqualifiedTableName(tree.Name(fmt.Sprintf("%s%d", prefix, tableIdx))), 1218 Defs: defs, 1219 Interleave: interleaveDef, 1220 } 1221 1222 // Create some random column families. 1223 if rng.Intn(2) == 0 { 1224 ColumnFamilyMutator(rng, ret) 1225 } 1226 1227 // Maybe add some storing columns. 1228 res, _ := IndexStoringMutator(rng, []tree.Statement{ret}) 1229 return res[0].(*tree.CreateTable) 1230 } 1231 1232 // ColumnFamilyMutator is mutations.StatementMutator, but lives here to prevent 1233 // dependency cycles with RandCreateTable. 1234 func ColumnFamilyMutator(rng *rand.Rand, stmt tree.Statement) (changed bool) { 1235 ast, ok := stmt.(*tree.CreateTable) 1236 if !ok { 1237 return false 1238 } 1239 1240 var columns []tree.Name 1241 for _, def := range ast.Defs { 1242 switch def := def.(type) { 1243 case *tree.FamilyTableDef: 1244 return false 1245 case *tree.ColumnTableDef: 1246 if def.HasColumnFamily() { 1247 return false 1248 } 1249 columns = append(columns, def.Name) 1250 } 1251 } 1252 1253 if len(columns) <= 1 { 1254 return false 1255 } 1256 1257 // Any columns not specified in column families 1258 // are auto assigned to the first family, so 1259 // there's no requirement to exhaust columns here. 1260 1261 rng.Shuffle(len(columns), func(i, j int) { 1262 columns[i], columns[j] = columns[j], columns[i] 1263 }) 1264 fd := &tree.FamilyTableDef{} 1265 for { 1266 if len(columns) == 0 { 1267 if len(fd.Columns) > 0 { 1268 ast.Defs = append(ast.Defs, fd) 1269 } 1270 break 1271 } 1272 fd.Columns = append(fd.Columns, columns[0]) 1273 columns = columns[1:] 1274 // 50% chance to make a new column family. 1275 if rng.Intn(2) != 0 { 1276 ast.Defs = append(ast.Defs, fd) 1277 fd = &tree.FamilyTableDef{} 1278 } 1279 } 1280 return true 1281 } 1282 1283 type tableInfo struct { 1284 columnNames []tree.Name 1285 pkCols []tree.Name 1286 } 1287 1288 // IndexStoringMutator is mutations.StatementMutator, but lives here to prevent 1289 // dependency cycles with RandCreateTable. 1290 func IndexStoringMutator(rng *rand.Rand, stmts []tree.Statement) ([]tree.Statement, bool) { 1291 changed := false 1292 tables := map[tree.Name]tableInfo{} 1293 getTableInfoFromCreateStatement := func(ct *tree.CreateTable) tableInfo { 1294 var columnNames []tree.Name 1295 var pkCols []tree.Name 1296 for _, def := range ct.Defs { 1297 switch ast := def.(type) { 1298 case *tree.ColumnTableDef: 1299 columnNames = append(columnNames, ast.Name) 1300 if ast.PrimaryKey.IsPrimaryKey { 1301 pkCols = []tree.Name{ast.Name} 1302 } 1303 case *tree.UniqueConstraintTableDef: 1304 if ast.PrimaryKey { 1305 for _, elem := range ast.Columns { 1306 pkCols = append(pkCols, elem.Column) 1307 } 1308 } 1309 } 1310 } 1311 return tableInfo{columnNames: columnNames, pkCols: pkCols} 1312 } 1313 mapFromIndexCols := func(cols []tree.Name) map[tree.Name]struct{} { 1314 colMap := map[tree.Name]struct{}{} 1315 for _, col := range cols { 1316 colMap[col] = struct{}{} 1317 } 1318 return colMap 1319 } 1320 generateStoringCols := func(rng *rand.Rand, tableCols []tree.Name, indexCols map[tree.Name]struct{}) []tree.Name { 1321 var storingCols []tree.Name 1322 for _, col := range tableCols { 1323 _, ok := indexCols[col] 1324 if ok { 1325 continue 1326 } 1327 if rng.Intn(2) == 0 { 1328 storingCols = append(storingCols, col) 1329 } 1330 } 1331 return storingCols 1332 } 1333 for _, stmt := range stmts { 1334 switch ast := stmt.(type) { 1335 case *tree.CreateIndex: 1336 if ast.Inverted { 1337 continue 1338 } 1339 tableInfo, ok := tables[ast.Table.ObjectName] 1340 if !ok { 1341 continue 1342 } 1343 // If we don't have a storing list, make one with 50% chance. 1344 if ast.Storing == nil && rng.Intn(2) == 0 { 1345 indexCols := mapFromIndexCols(tableInfo.pkCols) 1346 for _, elem := range ast.Columns { 1347 indexCols[elem.Column] = struct{}{} 1348 } 1349 ast.Storing = generateStoringCols(rng, tableInfo.columnNames, indexCols) 1350 changed = true 1351 } 1352 case *tree.CreateTable: 1353 // Write down this table for later. 1354 tableInfo := getTableInfoFromCreateStatement(ast) 1355 tables[ast.Table.ObjectName] = tableInfo 1356 for _, def := range ast.Defs { 1357 var idx *tree.IndexTableDef 1358 switch defType := def.(type) { 1359 case *tree.IndexTableDef: 1360 idx = defType 1361 case *tree.UniqueConstraintTableDef: 1362 if !defType.PrimaryKey { 1363 idx = &defType.IndexTableDef 1364 } 1365 } 1366 if idx == nil || idx.Inverted { 1367 continue 1368 } 1369 // If we don't have a storing list, make one with 50% chance. 1370 if idx.Storing == nil && rng.Intn(2) == 0 { 1371 indexCols := mapFromIndexCols(tableInfo.pkCols) 1372 for _, elem := range idx.Columns { 1373 indexCols[elem.Column] = struct{}{} 1374 } 1375 idx.Storing = generateStoringCols(rng, tableInfo.columnNames, indexCols) 1376 changed = true 1377 } 1378 } 1379 } 1380 } 1381 return stmts, changed 1382 } 1383 1384 // randColumnTableDef produces a random ColumnTableDef, with a random type and 1385 // nullability. 1386 func randColumnTableDef(rand *rand.Rand, tableIdx int, colIdx int) *tree.ColumnTableDef { 1387 columnDef := &tree.ColumnTableDef{ 1388 // We make a unique name for all columns by prefixing them with the table 1389 // index to make it easier to reference columns from different tables. 1390 Name: tree.Name(fmt.Sprintf("col%d_%d", tableIdx, colIdx)), 1391 Type: RandSortingType(rand), 1392 } 1393 columnDef.Nullable.Nullability = tree.Nullability(rand.Intn(int(tree.SilentNull) + 1)) 1394 return columnDef 1395 } 1396 1397 func randIndexTableDefFromCols( 1398 rng *rand.Rand, columnTableDefs []*tree.ColumnTableDef, 1399 ) tree.IndexTableDef { 1400 cpy := make([]*tree.ColumnTableDef, len(columnTableDefs)) 1401 copy(cpy, columnTableDefs) 1402 rng.Shuffle(len(cpy), func(i, j int) { cpy[i], cpy[j] = cpy[j], cpy[i] }) 1403 nCols := rng.Intn(len(cpy)) + 1 1404 1405 cols := cpy[:nCols] 1406 1407 indexElemList := make(tree.IndexElemList, 0, len(cols)) 1408 for i := range cols { 1409 semType := tree.MustBeStaticallyKnownType(cols[i].Type) 1410 if MustBeValueEncoded(semType) { 1411 continue 1412 } 1413 indexElemList = append(indexElemList, tree.IndexElem{ 1414 Column: cols[i].Name, 1415 Direction: tree.Direction(rng.Intn(int(tree.Descending) + 1)), 1416 }) 1417 } 1418 return tree.IndexTableDef{Columns: indexElemList} 1419 } 1420 1421 // The following variables are useful for testing. 1422 var ( 1423 // OneIntCol is a slice of one IntType. 1424 OneIntCol = []*types.T{types.Int} 1425 // TwoIntCols is a slice of two IntTypes. 1426 TwoIntCols = []*types.T{types.Int, types.Int} 1427 // ThreeIntCols is a slice of three IntTypes. 1428 ThreeIntCols = []*types.T{types.Int, types.Int, types.Int} 1429 // FourIntCols is a slice of four IntTypes. 1430 FourIntCols = []*types.T{types.Int, types.Int, types.Int, types.Int} 1431 ) 1432 1433 // MakeIntCols makes a slice of numCols IntTypes. 1434 func MakeIntCols(numCols int) []*types.T { 1435 ret := make([]*types.T, numCols) 1436 for i := 0; i < numCols; i++ { 1437 ret[i] = types.Int 1438 } 1439 return ret 1440 } 1441 1442 // IntEncDatum returns an EncDatum representation of DInt(i). 1443 func IntEncDatum(i int) EncDatum { 1444 return EncDatum{Datum: tree.NewDInt(tree.DInt(i))} 1445 } 1446 1447 // StrEncDatum returns an EncDatum representation of DString(s). 1448 func StrEncDatum(s string) EncDatum { 1449 return EncDatum{Datum: tree.NewDString(s)} 1450 } 1451 1452 // NullEncDatum returns and EncDatum representation of tree.DNull. 1453 func NullEncDatum() EncDatum { 1454 return EncDatum{Datum: tree.DNull} 1455 } 1456 1457 // GenEncDatumRowsInt converts rows of ints to rows of EncDatum DInts. 1458 // If an int is negative, the corresponding value is NULL. 1459 func GenEncDatumRowsInt(inputRows [][]int) EncDatumRows { 1460 rows := make(EncDatumRows, len(inputRows)) 1461 for i, inputRow := range inputRows { 1462 for _, x := range inputRow { 1463 if x < 0 { 1464 rows[i] = append(rows[i], NullEncDatum()) 1465 } else { 1466 rows[i] = append(rows[i], IntEncDatum(x)) 1467 } 1468 } 1469 } 1470 return rows 1471 } 1472 1473 // MakeIntRows constructs a numRows x numCols table where rows[i][j] = i + j. 1474 func MakeIntRows(numRows, numCols int) EncDatumRows { 1475 rows := make(EncDatumRows, numRows) 1476 for i := range rows { 1477 rows[i] = make(EncDatumRow, numCols) 1478 for j := 0; j < numCols; j++ { 1479 rows[i][j] = IntEncDatum(i + j) 1480 } 1481 } 1482 return rows 1483 } 1484 1485 // MakeRandIntRows constructs a numRows x numCols table where the values are random. 1486 func MakeRandIntRows(rng *rand.Rand, numRows int, numCols int) EncDatumRows { 1487 rows := make(EncDatumRows, numRows) 1488 for i := range rows { 1489 rows[i] = make(EncDatumRow, numCols) 1490 for j := 0; j < numCols; j++ { 1491 rows[i][j] = IntEncDatum(rng.Int()) 1492 } 1493 } 1494 return rows 1495 } 1496 1497 // MakeRandIntRowsInRange constructs a numRows * numCols table where the values 1498 // are random integers in the range [0, maxNum). 1499 func MakeRandIntRowsInRange( 1500 rng *rand.Rand, numRows int, numCols int, maxNum int, nullProbability float64, 1501 ) EncDatumRows { 1502 rows := make(EncDatumRows, numRows) 1503 for i := range rows { 1504 rows[i] = make(EncDatumRow, numCols) 1505 for j := 0; j < numCols; j++ { 1506 rows[i][j] = IntEncDatum(rng.Intn(maxNum)) 1507 if rng.Float64() < nullProbability { 1508 rows[i][j] = NullEncDatum() 1509 } 1510 } 1511 } 1512 return rows 1513 } 1514 1515 // MakeRepeatedIntRows constructs a numRows x numCols table where blocks of n 1516 // consecutive rows have the same value. 1517 func MakeRepeatedIntRows(n int, numRows int, numCols int) EncDatumRows { 1518 rows := make(EncDatumRows, numRows) 1519 for i := range rows { 1520 rows[i] = make(EncDatumRow, numCols) 1521 for j := 0; j < numCols; j++ { 1522 rows[i][j] = IntEncDatum(i/n + j) 1523 } 1524 } 1525 return rows 1526 }