MCPcopy Create free account
hub / github.com/dolthub/doltgresql / FindCommonType

Function FindCommonType

server/functions/framework/common_type.go:29–96  ·  view source on GitHub ↗

FindCommonType returns the common type that given types can convert to. Returns false if no implicit casts are needed to resolve the given types as the returned common type. https://www.postgresql.org/docs/15/typeconv-union-case.html

(ctx *sql.Context, types []*pgtypes.DoltgresType)

Source from the content-addressed store, hash-verified

27// to resolve the given types as the returned common type.
28// https://www.postgresql.org/docs/15/typeconv-union-case.html
29func FindCommonType(ctx *sql.Context, types []*pgtypes.DoltgresType) (_ *pgtypes.DoltgresType, requiresCasts bool, err error) {
30 candidateType := pgtypes.Unknown
31 differentTypes := false
32 for _, typ := range types {
33 if typ.ID == candidateType.ID {
34 continue
35 } else if candidateType.ID == pgtypes.Unknown.ID {
36 candidateType = typ
37 } else {
38 candidateType = pgtypes.Unknown
39 differentTypes = true
40 }
41 }
42 if !differentTypes {
43 if candidateType.ID == pgtypes.Unknown.ID {
44 // We require implicit casts from `unknown` to `text`
45 return pgtypes.Text, true, nil
46 }
47 return candidateType, false, nil
48 }
49 // We have different types if we've made it this far, so we're guaranteed to require implicit casts
50 requiresCasts = true
51 for _, typ := range types {
52 if candidateType.ID == pgtypes.Unknown.ID {
53 candidateType = typ
54 }
55 if typ.ID != pgtypes.Unknown.ID && candidateType.TypCategory != typ.TypCategory {
56 return nil, false, errors.Errorf("types %s and %s cannot be matched", candidateType.String(), typ.String())
57 }
58 }
59 castsColl, err := core.GetCastsCollectionFromContext(ctx, "")
60 if err != nil {
61 return nil, false, err
62 }
63 // Attempt to find the most general type (or the preferred type in the type category)
64 for _, typ := range types {
65 if typ.ID == pgtypes.Unknown.ID || typ.ID == candidateType.ID {
66 continue
67 } else if cast, err := castsColl.GetImplicitCast(ctx, typ, candidateType); err != nil || cast.ID.IsValid() {
68 if err != nil {
69 return nil, false, err
70 }
71 // typ can convert to the candidate type, so the candidate type is at least as general
72 continue
73 } else if cast, err = castsColl.GetImplicitCast(ctx, candidateType, typ); err != nil || cast.ID.IsValid() {
74 if err != nil {
75 return nil, false, err
76 }
77 // the candidate type can convert to typ, but not vice versa, so typ is likely more general
78 candidateType = typ
79 if candidateType.IsPreferred {
80 // We stop considering more types once we've found a preferred type
81 break
82 }
83 }
84 }
85 // Verify that all types have an implicit conversion to the candidate type
86 for _, typ := range types {

Callers 4

checkCompatibleTypesFunction · 0.92
transformValuesNodeFunction · 0.92
getTargetTypeMethod · 0.92
WithChildrenMethod · 0.92

Calls 5

ErrorfMethod · 0.65
StringMethod · 0.65
GetImplicitCastMethod · 0.65
IsValidMethod · 0.45

Tested by

no test coverage detected