Skip to content

Commit 1a751b5

Browse files
committed
types: add a .Canonical method to types
This adds a `.Canonical` method to types. This will be used by LDR to determine which type should be used as the parameter type when creating prepared statements to replicate arbitrary types. Canonical is needed because decoding a KV from the source cluster and querying a local row will return datums that match the canonical type. So we need a generic way to know the decoded Canonical type of all types. Release note: none Part of: #148310
1 parent ac39c2e commit 1a751b5

File tree

5 files changed

+618
-6
lines changed

5 files changed

+618
-6
lines changed

pkg/sql/randgen/datum.go

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -239,19 +239,16 @@ func RandDatumWithNullChance(
239239
}
240240
return tree.NewDJsonpath(*jp.AST)
241241
case types.TupleFamily:
242-
tuple := tree.DTuple{D: make(tree.Datums, len(typ.TupleContents()))}
243242
if nullChance == 0 {
244243
nullChance = 10
245244
}
245+
datums := make([]tree.Datum, len(typ.TupleContents()))
246246
for i := range typ.TupleContents() {
247-
tuple.D[i] = RandDatumWithNullChance(
247+
datums[i] = RandDatumWithNullChance(
248248
rng, typ.TupleContents()[i], nullChance, favorCommonData, targetColumnIsUnique,
249249
)
250250
}
251-
// Calling ResolvedType causes the internal TupleContents types to be
252-
// populated.
253-
tuple.ResolvedType()
254-
return &tuple
251+
return tree.NewDTuple(typ, datums...)
255252
case types.BitFamily:
256253
width := typ.Width()
257254
if width == 0 {
@@ -381,6 +378,9 @@ func RandArrayWithCommonDataChance(
381378
contents = RandArrayContentsType(rng)
382379
}
383380
arr := tree.NewDArray(contents)
381+
if err := arr.MaybeSetCustomOid(typ); err != nil {
382+
panic(err)
383+
}
384384
for i := 0; i < rng.Intn(10); i++ {
385385
if err :=
386386
arr.Append(
@@ -451,6 +451,8 @@ func adjustDatum(datum tree.Datum, typ *types.T) tree.Datum {
451451
}
452452
return datum
453453

454+
case types.OidFamily:
455+
return tree.NewDOidWithType(datum.(*tree.DOid).Oid, typ)
454456
default:
455457
return datum
456458
}

pkg/sql/randgen/types_test.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111

1212
"github.com/cockroachdb/cockroach/pkg/sql/types"
1313
"github.com/cockroachdb/cockroach/pkg/util/leaktest"
14+
"github.com/cockroachdb/cockroach/pkg/util/randutil"
1415
"github.com/cockroachdb/errors"
1516
)
1617

@@ -50,3 +51,27 @@ loop:
5051
t.Fatal(errors.Errorf("%s", s))
5152
}
5253
}
54+
55+
func TestCanonical(t *testing.T) {
56+
defer leaktest.AfterTest(t)()
57+
58+
rng, _ := randutil.NewTestRand()
59+
for range 1000 {
60+
typ := RandType(rng)
61+
62+
if !typ.Canonical().Equivalent(typ.WithoutTypeModifiers()) {
63+
t.Errorf("fail: canonical type of %+v should be equivalent to the type without modifiers", typ)
64+
}
65+
66+
datum := RandDatum(rng, typ, false)
67+
datumTyp := datum.ResolvedType()
68+
if !datumTyp.Equivalent(typ.Canonical()) {
69+
t.Errorf("fail: canonical type of %+v is %+v and the datum's type is %+v", typ, typ.Canonical(), datumTyp)
70+
}
71+
72+
if datumTyp.Oid() != typ.Canonical().Oid() {
73+
t.Errorf("fail type %+v: canonical type oid %d does not match the datum's (%+v) oid %+v",
74+
typ, typ.Canonical().Oid(), datum, datumTyp.Oid())
75+
}
76+
}
77+
}

pkg/sql/types/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ go_test(
3838
name = "types_test",
3939
size = "small",
4040
srcs = [
41+
"canonical_test.go",
4142
"types_test.go",
4243
"types_text_marshal_test.go",
4344
],

0 commit comments

Comments
 (0)