github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/types/types.go (about) 1 // Copyright 2015 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 types 12 13 import ( 14 "bytes" 15 "fmt" 16 "regexp" 17 "strings" 18 19 "github.com/cockroachdb/cockroach/pkg/geo/geopb" 20 "github.com/cockroachdb/cockroach/pkg/sql/lex" 21 "github.com/cockroachdb/cockroach/pkg/sql/oidext" 22 "github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgcode" 23 "github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgerror" 24 "github.com/cockroachdb/cockroach/pkg/util/errorutil/unimplemented" 25 "github.com/cockroachdb/cockroach/pkg/util/protoutil" 26 "github.com/cockroachdb/errors" 27 "github.com/lib/pq/oid" 28 ) 29 30 // T is an instance of a SQL scalar, array, or tuple type. It describes the 31 // domain of possible values which a column can return, or to which an 32 // expression can evaluate. The type system does not differentiate between 33 // nullable and non-nullable types. It is up to the caller to store that 34 // information separately if it is needed. Here are some example types: 35 // 36 // INT4 - any 32-bit integer 37 // DECIMAL(10, 3) - any base-10 value with at most 10 digits, with 38 // up to 3 to right of decimal point 39 // FLOAT[] - array of 64-bit IEEE 754 floating-point values 40 // TUPLE[TIME, VARCHAR(20)] - any pair of values where first value is a time 41 // of day and the second value is a string having 42 // up to 20 characters 43 // 44 // Fundamentally, a type consists of the following attributes, each of which has 45 // a corresponding accessor method. Some of these attributes are only defined 46 // for a subset of types. See the method comments for more details. 47 // 48 // Family - equivalence group of the type (enumeration) 49 // Oid - Postgres Object ID that describes the type (enumeration) 50 // Precision - maximum accuracy of the type (numeric) 51 // Width - maximum size or scale of the type (numeric) 52 // Locale - location which governs sorting, formatting, etc. (string) 53 // ArrayContents - array element type (T) 54 // TupleContents - slice of types of each tuple field ([]*T) 55 // TupleLabels - slice of labels of each tuple field ([]string) 56 // 57 // Some types are not currently allowed as the type of a column (e.g. nested 58 // arrays). Other usages of the types package may have similar restrictions. 59 // Each such caller is responsible for enforcing their own restrictions; it's 60 // not the concern of the types package. 61 // 62 // Implementation-wise, types.T wraps a protobuf-generated InternalType struct. 63 // The generated protobuf code defines the struct fields, marshals/unmarshals 64 // them, formats a string representation, etc. Meanwhile, the wrapper types.T 65 // struct overrides the Marshal/Unmarshal methods in order to map to/from older 66 // persisted InternalType representations. For example, older versions of 67 // InternalType (previously called ColumnType) used a VisibleType field to 68 // represent INT2, whereas newer versions use Width/Oid. Unmarshal upgrades from 69 // this old format to the new, and Marshal downgrades, thus preserving backwards 70 // compatibility. 71 // 72 // Simple (unary) scalars types 73 // ---------------------------- 74 // 75 // | SQL type | Family | Oid | Precision | Width | 76 // |-------------------|----------------|---------------|-----------|-------| 77 // | NULL (unknown) | UNKNOWN | T_unknown | 0 | 0 | 78 // | BOOL | BOOL | T_bool | 0 | 0 | 79 // | DATE | DATE | T_date | 0 | 0 | 80 // | TIMESTAMP | TIMESTAMP | T_timestamp | 0 | 0 | 81 // | INTERVAL | INTERVAL | T_interval | 0 | 0 | 82 // | TIMESTAMPTZ | TIMESTAMPTZ | T_timestamptz | 0 | 0 | 83 // | OID | OID | T_oid | 0 | 0 | 84 // | UUID | UUID | T_uuid | 0 | 0 | 85 // | INET | INET | T_inet | 0 | 0 | 86 // | TIME | TIME | T_time | 0 | 0 | 87 // | TIMETZ | TIMETZ | T_timetz | 0 | 0 | 88 // | JSON | JSONB | T_jsonb | 0 | 0 | 89 // | JSONB | JSONB | T_jsonb | 0 | 0 | 90 // | | | | | | 91 // | BYTES | BYTES | T_bytea | 0 | 0 | 92 // | | | | | | 93 // | STRING | STRING | T_text | 0 | 0 | 94 // | STRING(N) | STRING | T_text | 0 | N | 95 // | VARCHAR | STRING | T_varchar | 0 | 0 | 96 // | VARCHAR(N) | STRING | T_varchar | 0 | N | 97 // | CHAR | STRING | T_bpchar | 0 | 1 | 98 // | CHAR(N) | STRING | T_bpchar | 0 | N | 99 // | "char" | STRING | T_char | 0 | 0 | 100 // | NAME | STRING | T_name | 0 | 0 | 101 // | | | | | | 102 // | STRING COLLATE en | COLLATEDSTRING | T_text | 0 | 0 | 103 // | STRING(N) COL... | COLLATEDSTRING | T_text | 0 | N | 104 // | VARCHAR COL... | COLLATEDSTRING | T_varchar | 0 | N | 105 // | VARCHAR(N) COL... | COLLATEDSTRING | T_varchar | 0 | N | 106 // | CHAR COL... | COLLATEDSTRING | T_bpchar | 0 | 1 | 107 // | CHAR(N) COL... | COLLATEDSTRING | T_bpchar | 0 | N | 108 // | "char" COL... | COLLATEDSTRING | T_char | 0 | 0 | 109 // | | | | | | 110 // | DECIMAL | DECIMAL | T_decimal | 0 | 0 | 111 // | DECIMAL(N) | DECIMAL | T_decimal | N | 0 | 112 // | DECIMAL(N,M) | DECIMAL | T_decimal | N | M | 113 // | | | | | | 114 // | FLOAT8 | FLOAT | T_float8 | 0 | 0 | 115 // | FLOAT4 | FLOAT | T_float4 | 0 | 0 | 116 // | | | | | | 117 // | BIT | BIT | T_bit | 0 | 1 | 118 // | BIT(N) | BIT | T_bit | 0 | N | 119 // | VARBIT | BIT | T_varbit | 0 | 0 | 120 // | VARBIT(N) | BIT | T_varbit | 0 | N | 121 // | | | | | | 122 // | INT,INTEGER | INT | T_int8 | 0 | 64 | 123 // | INT2,SMALLINT | INT | T_int2 | 0 | 16 | 124 // | INT4 | INT | T_int4 | 0 | 32 | 125 // | INT8,INT64,BIGINT | INT | T_int8 | 0 | 64 | 126 // 127 // Tuple types 128 // ----------- 129 // 130 // These cannot (yet) be used in tables but are used in DistSQL flow 131 // processors for queries that have tuple-typed intermediate results. 132 // 133 // | Field | Description | 134 // |-----------------|---------------------------------------------------------| 135 // | Family | TupleFamily | 136 // | Oid | T_record | 137 // | TupleContents | Contains tuple field types (can be recursively defined) | 138 // | TupleLabels | Contains labels for each tuple field | 139 // 140 // Array types 141 // ----------- 142 // 143 // | Field | Description | 144 // |-----------------|---------------------------------------------------------| 145 // | Family | ArrayFamily | 146 // | Oid | T__XXX (double underscores), where XXX is the Oid name | 147 // | | of a scalar type | 148 // | ArrayContents | Type of array elements (scalar, array, or tuple) | 149 // 150 // There are two special ARRAY types: 151 // 152 // | SQL type | Family | Oid | ArrayContents | 153 // |-------------------|----------------|---------------|---------------| 154 // | INT2VECTOR | ARRAY | T_int2vector | Int | 155 // | OIDVECTOR | ARRAY | T_oidvector | Oid | 156 // 157 // When these types are themselves made into arrays, the Oids become T__int2vector and 158 // T__oidvector, respectively. 159 // 160 // User defined types 161 // ------------------ 162 // 163 // * Enums 164 // | Field | Description | 165 // |---------------|--------------------------------------------| 166 // | Family | EnumFamily | 167 // | Oid | A unique OID generated upon enum creation | 168 // 169 // See types.proto for the corresponding proto definition. Its automatic 170 // type declaration is suppressed in the proto so that it is possible to 171 // add additional fields to T without serializing them. 172 type T struct { 173 // InternalType should never be directly referenced outside this package. The 174 // only reason it is exported is because gogoproto panics when printing the 175 // string representation of an unexported field. This is a problem when this 176 // struct is embedded in a larger struct (like a ColumnDescriptor). 177 InternalType InternalType 178 179 // Fields that are only populated when hydrating from a user defined 180 // type descriptor. It is assumed that a user defined type is only used 181 // once its metadata has been hydrated through the process of type resolution. 182 TypeMeta UserDefinedTypeMetadata 183 } 184 185 // UserDefinedTypeMetadata contains metadata needed for runtime 186 // operations on user defined types. The metadata must be read only. 187 type UserDefinedTypeMetadata struct { 188 // Name is the resolved name of this type. 189 Name *UserDefinedTypeName 190 191 // enumData is non-nil iff the metadata is for an ENUM type. 192 EnumData *EnumMetadata 193 } 194 195 // EnumMetadata is metadata about an ENUM needed for evaluation. 196 type EnumMetadata struct { 197 // PhysicalRepresentations is a slice of the byte array 198 // physical representations of enum members. 199 PhysicalRepresentations [][]byte 200 // LogicalRepresentations is a slice of the string logical 201 // representations of enum members. 202 LogicalRepresentations []string 203 // TODO (rohany): For small enums, having a map would be slower 204 // than just an array. Investigate at what point the tradeoff 205 // should occur, if at all. 206 } 207 208 func (e *EnumMetadata) debugString() string { 209 return fmt.Sprintf( 210 "PhysicalReps: %v; LogicalReps: %s", 211 e.PhysicalRepresentations, 212 e.LogicalRepresentations, 213 ) 214 } 215 216 // UserDefinedTypeName is a struct representing a qualified user defined 217 // type name. We redefine a common struct from higher level packages. We 218 // do so because proto will panic if any members of a proto struct are 219 // private. Rather than expose private members of higher level packages, 220 // we define a separate type here to be safe. 221 type UserDefinedTypeName struct { 222 Catalog string 223 Schema string 224 Name string 225 } 226 227 // MakeUserDefinedTypeName creates a user defined type name. 228 func MakeUserDefinedTypeName(catalog, schema, name string) *UserDefinedTypeName { 229 return &UserDefinedTypeName{ 230 Catalog: catalog, 231 Schema: schema, 232 Name: name, 233 } 234 } 235 236 // Basename returns the unqualified name. 237 func (u UserDefinedTypeName) Basename() string { 238 return u.Name 239 } 240 241 // FQName returns the fully qualified name. 242 func (u UserDefinedTypeName) FQName() string { 243 var sb strings.Builder 244 sb.WriteString(u.Catalog) 245 sb.WriteString(".") 246 sb.WriteString(u.Schema) 247 sb.WriteString(".") 248 sb.WriteString(u.Name) 249 return sb.String() 250 } 251 252 // Convenience list of pre-constructed types. Caller code can use any of these 253 // types, or use the MakeXXX methods to construct a custom type that is not 254 // listed here (e.g. if a custom width is needed). 255 var ( 256 // Unknown is the type of an expression that statically evaluates to NULL. 257 // This type should never be returned for an expression that does not *always* 258 // evaluate to NULL. 259 Unknown = &T{InternalType: InternalType{ 260 Family: UnknownFamily, Oid: oid.T_unknown, Locale: &emptyLocale}} 261 262 // Bool is the type of a boolean true/false value. 263 Bool = &T{InternalType: InternalType{ 264 Family: BoolFamily, Oid: oid.T_bool, Locale: &emptyLocale}} 265 266 // VarBit is the type of an ordered list of bits (0 or 1 valued), with no 267 // specified limit on the count of bits. 268 VarBit = &T{InternalType: InternalType{ 269 Family: BitFamily, Oid: oid.T_varbit, Locale: &emptyLocale}} 270 271 // Int is the type of a 64-bit signed integer. This is the canonical type 272 // for IntFamily. 273 Int = &T{InternalType: InternalType{ 274 Family: IntFamily, Width: 64, Oid: oid.T_int8, Locale: &emptyLocale}} 275 276 // Int4 is the type of a 32-bit signed integer. 277 Int4 = &T{InternalType: InternalType{ 278 Family: IntFamily, Width: 32, Oid: oid.T_int4, Locale: &emptyLocale}} 279 280 // Int2 is the type of a 16-bit signed integer. 281 Int2 = &T{InternalType: InternalType{ 282 Family: IntFamily, Width: 16, Oid: oid.T_int2, Locale: &emptyLocale}} 283 284 // Float is the type of a 64-bit base-2 floating-point number (IEEE 754). 285 // This is the canonical type for FloatFamily. 286 Float = &T{InternalType: InternalType{ 287 Family: FloatFamily, Width: 64, Oid: oid.T_float8, Locale: &emptyLocale}} 288 289 // Float4 is the type of a 32-bit base-2 floating-point number (IEEE 754). 290 Float4 = &T{InternalType: InternalType{ 291 Family: FloatFamily, Width: 32, Oid: oid.T_float4, Locale: &emptyLocale}} 292 293 // Decimal is the type of a base-10 floating-point number, with no specified 294 // limit on precision (number of digits) or scale (digits to right of decimal 295 // point). 296 Decimal = &T{InternalType: InternalType{ 297 Family: DecimalFamily, Oid: oid.T_numeric, Locale: &emptyLocale}} 298 299 // String is the type of a Unicode string, with no specified limit on the 300 // count of characters. This is the canonical type for StringFamily. It is 301 // reported as STRING in SHOW CREATE but "text" in introspection for 302 // compatibility with PostgreSQL. 303 String = &T{InternalType: InternalType{ 304 Family: StringFamily, Oid: oid.T_text, Locale: &emptyLocale}} 305 306 // VarChar is equivalent to String, but has a differing OID (T_varchar), 307 // which makes it show up differently when displayed. It is reported as 308 // VARCHAR in SHOW CREATE and "character varying" in introspection for 309 // compatibility with PostgreSQL. 310 VarChar = &T{InternalType: InternalType{ 311 Family: StringFamily, Oid: oid.T_varchar, Locale: &emptyLocale}} 312 313 // Name is a type-alias for String with a different OID (T_name). It is 314 // reported as NAME in SHOW CREATE and "name" in introspection for 315 // compatibility with PostgreSQL. 316 Name = &T{InternalType: InternalType{ 317 Family: StringFamily, Oid: oid.T_name, Locale: &emptyLocale}} 318 319 // Bytes is the type of a list of raw byte values. 320 Bytes = &T{InternalType: InternalType{ 321 Family: BytesFamily, Oid: oid.T_bytea, Locale: &emptyLocale}} 322 323 // Date is the type of a value specifying year, month, day (with no time 324 // component). There is no timezone associated with it. For example: 325 // 326 // YYYY-MM-DD 327 // 328 Date = &T{InternalType: InternalType{ 329 Family: DateFamily, Oid: oid.T_date, Locale: &emptyLocale}} 330 331 // Time is the type of a value specifying hour, minute, second (with no date 332 // component). By default, it has microsecond precision. There is no timezone 333 // associated with it. For example: 334 // 335 // HH:MM:SS.ssssss 336 // 337 Time = &T{InternalType: InternalType{ 338 Family: TimeFamily, 339 Precision: 0, 340 TimePrecisionIsSet: false, 341 Oid: oid.T_time, 342 Locale: &emptyLocale, 343 }} 344 345 // TimeTZ is the type specifying hour, minute, second and timezone with 346 // no date component. By default, it has microsecond precision. 347 // For example: 348 // 349 // HH:MM:SS.ssssss+-ZZ:ZZ 350 TimeTZ = &T{InternalType: InternalType{ 351 Family: TimeTZFamily, 352 Precision: 0, 353 TimePrecisionIsSet: false, 354 Oid: oid.T_timetz, 355 Locale: &emptyLocale, 356 }} 357 358 // Timestamp is the type of a value specifying year, month, day, hour, minute, 359 // and second, but with no associated timezone. By default, it has microsecond 360 // precision. For example: 361 // 362 // YYYY-MM-DD HH:MM:SS.ssssss 363 // 364 Timestamp = &T{InternalType: InternalType{ 365 Family: TimestampFamily, 366 Precision: 0, 367 TimePrecisionIsSet: false, 368 Oid: oid.T_timestamp, 369 Locale: &emptyLocale, 370 }} 371 372 // TimestampTZ is the type of a value specifying year, month, day, hour, 373 // minute, and second, as well as an associated timezone. By default, it has 374 // microsecond precision. For example: 375 // 376 // YYYY-MM-DD HH:MM:SS.ssssss+-ZZ:ZZ 377 // 378 TimestampTZ = &T{InternalType: InternalType{ 379 Family: TimestampTZFamily, 380 Precision: 0, 381 TimePrecisionIsSet: false, 382 Oid: oid.T_timestamptz, 383 Locale: &emptyLocale, 384 }} 385 386 // Interval is the type of a value describing a duration of time. By default, 387 // it has microsecond precision. 388 Interval = &T{InternalType: InternalType{ 389 Family: IntervalFamily, 390 Precision: 0, 391 TimePrecisionIsSet: false, 392 Oid: oid.T_interval, 393 Locale: &emptyLocale, 394 IntervalDurationField: &IntervalDurationField{}, 395 }} 396 397 // Jsonb is the type of a JavaScript Object Notation (JSON) value that is 398 // stored in a decomposed binary format (hence the "b" in jsonb). 399 Jsonb = &T{InternalType: InternalType{ 400 Family: JsonFamily, Oid: oid.T_jsonb, Locale: &emptyLocale}} 401 402 // Uuid is the type of a universally unique identifier (UUID), which is a 403 // 128-bit quantity that is very unlikely to ever be generated again, and so 404 // can be relied on to be distinct from all other UUID values. 405 Uuid = &T{InternalType: InternalType{ 406 Family: UuidFamily, Oid: oid.T_uuid, Locale: &emptyLocale}} 407 408 // INet is the type of an IPv4 or IPv6 network address. For example: 409 // 410 // 192.168.100.128/25 411 // FE80:CD00:0:CDE:1257:0:211E:729C 412 // 413 INet = &T{InternalType: InternalType{ 414 Family: INetFamily, Oid: oid.T_inet, Locale: &emptyLocale}} 415 416 // Geometry is the type of a geospatial Geometry object. 417 Geometry = &T{ 418 InternalType: InternalType{ 419 Family: GeometryFamily, 420 Oid: oidext.T_geometry, 421 Locale: &emptyLocale, 422 GeoMetadata: &GeoMetadata{}, 423 }, 424 } 425 426 // Geography is the type of a geospatial Geography object. 427 Geography = &T{ 428 InternalType: InternalType{ 429 Family: GeographyFamily, 430 Oid: oidext.T_geography, 431 Locale: &emptyLocale, 432 GeoMetadata: &GeoMetadata{}, 433 }, 434 } 435 436 // Scalar contains all types that meet this criteria: 437 // 438 // 1. Scalar type (no ArrayFamily or TupleFamily types). 439 // 2. Non-ambiguous type (no UnknownFamily or AnyFamily types). 440 // 3. Canonical type for one of the type families. 441 // 442 Scalar = []*T{ 443 Bool, 444 Int, 445 Float, 446 Decimal, 447 Date, 448 Timestamp, 449 Interval, 450 Geography, 451 Geometry, 452 String, 453 Bytes, 454 TimestampTZ, 455 Oid, 456 Uuid, 457 INet, 458 Time, 459 TimeTZ, 460 Jsonb, 461 VarBit, 462 } 463 464 // Any is a special type used only during static analysis as a wildcard type 465 // that matches any other type, including scalar, array, and tuple types. 466 // Execution-time values should never have this type. As an example of its 467 // use, many SQL builtin functions allow an input value to be of any type, 468 // and so use this type in their static definitions. 469 Any = &T{InternalType: InternalType{ 470 Family: AnyFamily, Oid: oid.T_anyelement, Locale: &emptyLocale}} 471 472 // AnyArray is a special type used only during static analysis as a wildcard 473 // type that matches an array having elements of any (uniform) type (including 474 // nested array types). Execution-time values should never have this type. 475 AnyArray = &T{InternalType: InternalType{ 476 Family: ArrayFamily, ArrayContents: Any, Oid: oid.T_anyarray, Locale: &emptyLocale}} 477 478 // AnyEnum is a special type only used during static analysis as a wildcard 479 // type that matches an possible enum value. Execution-time values should 480 // never have this type. 481 AnyEnum = &T{InternalType: InternalType{ 482 Family: EnumFamily, Locale: &emptyLocale, Oid: oid.T_anyenum}} 483 484 // AnyTuple is a special type used only during static analysis as a wildcard 485 // type that matches a tuple with any number of fields of any type (including 486 // tuple types). Execution-time values should never have this type. 487 AnyTuple = &T{InternalType: InternalType{ 488 Family: TupleFamily, TupleContents: []*T{Any}, Oid: oid.T_record, Locale: &emptyLocale}} 489 490 // AnyCollatedString is a special type used only during static analysis as a 491 // wildcard type that matches a collated string with any locale. Execution- 492 // time values should never have this type. 493 AnyCollatedString = &T{InternalType: InternalType{ 494 Family: CollatedStringFamily, Oid: oid.T_text, Locale: &emptyLocale}} 495 496 // EmptyTuple is the tuple type with no fields. Note that this is different 497 // than AnyTuple, which is a wildcard type. 498 EmptyTuple = &T{InternalType: InternalType{ 499 Family: TupleFamily, Oid: oid.T_record, Locale: &emptyLocale}} 500 501 // StringArray is the type of an array value having String-typed elements. 502 StringArray = &T{InternalType: InternalType{ 503 Family: ArrayFamily, ArrayContents: String, Oid: oid.T__text, Locale: &emptyLocale}} 504 505 // IntArray is the type of an array value having Int-typed elements. 506 IntArray = &T{InternalType: InternalType{ 507 Family: ArrayFamily, ArrayContents: Int, Oid: oid.T__int8, Locale: &emptyLocale}} 508 509 // FloatArray is the type of an array value having Float-typed elements. 510 FloatArray = &T{InternalType: InternalType{ 511 Family: ArrayFamily, ArrayContents: Float, Oid: oid.T__float8, Locale: &emptyLocale}} 512 513 // DecimalArray is the type of an array value having Decimal-typed elements. 514 DecimalArray = &T{InternalType: InternalType{ 515 Family: ArrayFamily, ArrayContents: Decimal, Oid: oid.T__numeric, Locale: &emptyLocale}} 516 517 // Int2Vector is a type-alias for an array of Int2 values with a different 518 // OID (T_int2vector instead of T__int2). It is a special VECTOR type used 519 // by Postgres in system tables. Int2vectors are 0-indexed, unlike normal arrays. 520 Int2Vector = &T{InternalType: InternalType{ 521 Family: ArrayFamily, Oid: oid.T_int2vector, ArrayContents: Int2, Locale: &emptyLocale}} 522 ) 523 524 // Unexported wrapper types. 525 var ( 526 // typeBit is the SQL BIT type. It is not exported to avoid confusion with 527 // the VarBit type, and confusion over whether its default Width is 528 // unspecified or is 1. More commonly used instead is the VarBit type. 529 typeBit = &T{InternalType: InternalType{ 530 Family: BitFamily, Oid: oid.T_bit, Locale: &emptyLocale}} 531 532 // typeBpChar is the "standard SQL" string type of fixed length, where "bp" 533 // stands for "blank padded". It is not exported to avoid confusion with 534 // typeQChar, as well as confusion over its default width. 535 // 536 // It is reported as CHAR in SHOW CREATE and "character" in introspection for 537 // compatibility with PostgreSQL. 538 // 539 // Its default maximum with is 1. It always has a maximum width. 540 typeBpChar = &T{InternalType: InternalType{ 541 Family: StringFamily, Oid: oid.T_bpchar, Locale: &emptyLocale}} 542 543 // typeQChar is a special PostgreSQL-only type supported for compatibility. 544 // It behaves like VARCHAR, its maximum width cannot be modified, and has a 545 // peculiar name in the syntax and introspection. It is not exported to avoid 546 // confusion with typeBpChar, as well as confusion over its default width. 547 // 548 // It is reported as "char" (with double quotes included) in SHOW CREATE and 549 // "char" in introspection for compatibility with PostgreSQL. 550 typeQChar = &T{InternalType: InternalType{ 551 Family: StringFamily, Oid: oid.T_char, Locale: &emptyLocale}} 552 ) 553 554 const ( 555 // Deprecated after 19.1, since it's now represented using the Oid field. 556 name Family = 11 557 558 // Deprecated after 19.1, since it's now represented using the Oid field. 559 int2vector Family = 200 560 561 // Deprecated after 19.1, since it's now represented using the Oid field. 562 oidvector Family = 201 563 564 visibleNONE = 0 565 566 // Deprecated after 2.1, since it's no longer used. 567 visibleINTEGER = 1 568 569 // Deprecated after 2.1, since it's now represented using the Width field. 570 visibleSMALLINT = 2 571 572 // Deprecated after 2.1, since it's now represented using the Width field. 573 visibleBIGINT = 3 574 575 // Deprecated after 2.0, since the original BIT representation was buggy. 576 visibleBIT = 4 577 578 // Deprecated after 19.1, since it's now represented using the Width field. 579 visibleREAL = 5 580 581 // Deprecated after 2.1, since it's now represented using the Width field. 582 visibleDOUBLE = 6 583 584 // Deprecated after 19.1, since it's now represented using the Oid field. 585 visibleVARCHAR = 7 586 587 // Deprecated after 19.1, since it's now represented using the Oid field. 588 visibleCHAR = 8 589 590 // Deprecated after 19.1, since it's now represented using the Oid field. 591 visibleQCHAR = 9 592 593 // Deprecated after 19.1, since it's now represented using the Oid field. 594 visibleVARBIT = 10 595 596 // OID returned for the unknown[] array type. PG has no OID for this case. 597 unknownArrayOid = 0 598 ) 599 600 const ( 601 // defaultTimePrecision is the default precision to return for time families 602 // if time is not set. 603 defaultTimePrecision = 6 604 ) 605 606 var ( 607 emptyLocale = "" 608 ) 609 610 // MakeScalar constructs a new instance of a scalar type (i.e. not array or 611 // tuple types) using the provided fields. 612 func MakeScalar(family Family, o oid.Oid, precision, width int32, locale string) *T { 613 t := OidToType[o] 614 if family != t.Family() { 615 if family != CollatedStringFamily || StringFamily != t.Family() { 616 panic(errors.AssertionFailedf("oid %d does not match %s", o, family)) 617 } 618 } 619 if family == ArrayFamily || family == TupleFamily { 620 panic(errors.AssertionFailedf("cannot make non-scalar type %s", family)) 621 } 622 if family != CollatedStringFamily && locale != "" { 623 panic(errors.AssertionFailedf("non-collation type cannot have locale %s", locale)) 624 } 625 626 timePrecisionIsSet := false 627 var intervalDurationField *IntervalDurationField 628 var geoMetadata *GeoMetadata 629 switch family { 630 case IntervalFamily: 631 intervalDurationField = &IntervalDurationField{} 632 if precision < 0 || precision > 6 { 633 panic(errors.AssertionFailedf("precision must be between 0 and 6 inclusive")) 634 } 635 timePrecisionIsSet = true 636 case TimestampFamily, TimestampTZFamily, TimeFamily, TimeTZFamily: 637 if precision < 0 || precision > 6 { 638 panic(errors.AssertionFailedf("precision must be between 0 and 6 inclusive")) 639 } 640 timePrecisionIsSet = true 641 case DecimalFamily: 642 if precision < 0 { 643 panic(errors.AssertionFailedf("negative precision is not allowed")) 644 } 645 default: 646 if precision != 0 { 647 panic(errors.AssertionFailedf("type %s cannot have precision", family)) 648 } 649 } 650 651 if width < 0 { 652 panic(errors.AssertionFailedf("negative width is not allowed")) 653 } 654 switch family { 655 case IntFamily: 656 switch width { 657 case 16, 32, 64: 658 default: 659 panic(errors.AssertionFailedf("invalid width %d for IntFamily type", width)) 660 } 661 case FloatFamily: 662 switch width { 663 case 32, 64: 664 default: 665 panic(errors.AssertionFailedf("invalid width %d for FloatFamily type", width)) 666 } 667 case DecimalFamily: 668 if width > precision { 669 panic(errors.AssertionFailedf( 670 "decimal scale %d cannot be larger than precision %d", width, precision)) 671 } 672 case StringFamily, BytesFamily, CollatedStringFamily, BitFamily: 673 // These types can have any width. 674 case GeometryFamily: 675 geoMetadata = &GeoMetadata{} 676 case GeographyFamily: 677 geoMetadata = &GeoMetadata{} 678 default: 679 if width != 0 { 680 panic(errors.AssertionFailedf("type %s cannot have width", family)) 681 } 682 } 683 684 return &T{InternalType: InternalType{ 685 Family: family, 686 Oid: o, 687 Precision: precision, 688 TimePrecisionIsSet: timePrecisionIsSet, 689 Width: width, 690 Locale: &locale, 691 IntervalDurationField: intervalDurationField, 692 GeoMetadata: geoMetadata, 693 }} 694 } 695 696 // MakeBit constructs a new instance of the BIT type (oid = T_bit) having the 697 // given max # bits (0 = unspecified number). 698 func MakeBit(width int32) *T { 699 if width == 0 { 700 return typeBit 701 } 702 if width < 0 { 703 panic(errors.AssertionFailedf("width %d cannot be negative", width)) 704 } 705 return &T{InternalType: InternalType{ 706 Family: BitFamily, Oid: oid.T_bit, Width: width, Locale: &emptyLocale}} 707 } 708 709 // MakeVarBit constructs a new instance of the BIT type (oid = T_varbit) having 710 // the given max # bits (0 = unspecified number). 711 func MakeVarBit(width int32) *T { 712 if width == 0 { 713 return VarBit 714 } 715 if width < 0 { 716 panic(errors.AssertionFailedf("width %d cannot be negative", width)) 717 } 718 return &T{InternalType: InternalType{ 719 Family: BitFamily, Width: width, Oid: oid.T_varbit, Locale: &emptyLocale}} 720 } 721 722 // MakeString constructs a new instance of the STRING type (oid = T_text) having 723 // the given max # characters (0 = unspecified number). 724 func MakeString(width int32) *T { 725 if width == 0 { 726 return String 727 } 728 if width < 0 { 729 panic(errors.AssertionFailedf("width %d cannot be negative", width)) 730 } 731 return &T{InternalType: InternalType{ 732 Family: StringFamily, Oid: oid.T_text, Width: width, Locale: &emptyLocale}} 733 } 734 735 // MakeVarChar constructs a new instance of the VARCHAR type (oid = T_varchar) 736 // having the given max # characters (0 = unspecified number). 737 func MakeVarChar(width int32) *T { 738 if width == 0 { 739 return VarChar 740 } 741 if width < 0 { 742 panic(errors.AssertionFailedf("width %d cannot be negative", width)) 743 } 744 return &T{InternalType: InternalType{ 745 Family: StringFamily, Oid: oid.T_varchar, Width: width, Locale: &emptyLocale}} 746 } 747 748 // MakeChar constructs a new instance of the CHAR type (oid = T_bpchar) having 749 // the given max # characters (0 = unspecified number). 750 func MakeChar(width int32) *T { 751 if width == 0 { 752 return typeBpChar 753 } 754 if width < 0 { 755 panic(errors.AssertionFailedf("width %d cannot be negative", width)) 756 } 757 return &T{InternalType: InternalType{ 758 Family: StringFamily, Oid: oid.T_bpchar, Width: width, Locale: &emptyLocale}} 759 } 760 761 // MakeQChar constructs a new instance of the "char" type (oid = T_char) having 762 // the given max # characters (0 = unspecified number). 763 func MakeQChar(width int32) *T { 764 if width == 0 { 765 return typeQChar 766 } 767 return &T{InternalType: InternalType{ 768 Family: StringFamily, Oid: oid.T_char, Width: width, Locale: &emptyLocale}} 769 } 770 771 // MakeCollatedString constructs a new instance of a CollatedStringFamily type 772 // that is collated according to the given locale. The new type is based upon 773 // the given string type, having the same oid and width values. For example: 774 // 775 // STRING => STRING COLLATE EN 776 // VARCHAR(20) => VARCHAR(20) COLLATE EN 777 // 778 func MakeCollatedString(strType *T, locale string) *T { 779 switch strType.Oid() { 780 case oid.T_text, oid.T_varchar, oid.T_bpchar, oid.T_char, oid.T_name: 781 return &T{InternalType: InternalType{ 782 Family: CollatedStringFamily, Oid: strType.Oid(), Width: strType.Width(), Locale: &locale}} 783 } 784 panic(errors.AssertionFailedf("cannot apply collation to non-string type: %s", strType)) 785 } 786 787 // MakeDecimal constructs a new instance of a DECIMAL type (oid = T_numeric) 788 // that has at most "precision" # of decimal digits (0 = unspecified number of 789 // digits) and at most "scale" # of decimal digits after the decimal point 790 // (0 = unspecified number of digits). scale must be <= precision. 791 func MakeDecimal(precision, scale int32) *T { 792 if precision == 0 && scale == 0 { 793 return Decimal 794 } 795 if precision < 0 { 796 panic(errors.AssertionFailedf("precision %d cannot be negative", precision)) 797 } 798 if scale < 0 { 799 panic(errors.AssertionFailedf("scale %d cannot be negative", scale)) 800 } 801 if scale > precision { 802 panic(errors.AssertionFailedf( 803 "scale %d cannot be larger than precision %d", scale, precision)) 804 } 805 return &T{InternalType: InternalType{ 806 Family: DecimalFamily, 807 Oid: oid.T_numeric, 808 Precision: precision, 809 Width: scale, 810 Locale: &emptyLocale, 811 }} 812 } 813 814 // MakeTime constructs a new instance of a TIME type (oid = T_time) that has at 815 // most the given number of fractional second digits. 816 // 817 // To use the default precision, use the `Time` variable. 818 func MakeTime(precision int32) *T { 819 return &T{InternalType: InternalType{ 820 Family: TimeFamily, 821 Oid: oid.T_time, 822 Precision: precision, 823 TimePrecisionIsSet: true, 824 Locale: &emptyLocale, 825 }} 826 } 827 828 // MakeTimeTZ constructs a new instance of a TIMETZ type (oid = T_timetz) that 829 // has at most the given number of fractional second digits. 830 // 831 // To use the default precision, use the `TimeTZ` variable. 832 func MakeTimeTZ(precision int32) *T { 833 return &T{InternalType: InternalType{ 834 Family: TimeTZFamily, 835 Oid: oid.T_timetz, 836 Precision: precision, 837 TimePrecisionIsSet: true, 838 Locale: &emptyLocale, 839 }} 840 } 841 842 // MakeGeometry constructs a new instance of a GEOMETRY type (oid = T_geometry) 843 // that has the given shape and SRID. 844 func MakeGeometry(shape geopb.Shape, srid geopb.SRID) *T { 845 return &T{InternalType: InternalType{ 846 Family: GeometryFamily, 847 Oid: oidext.T_geometry, 848 Locale: &emptyLocale, 849 GeoMetadata: &GeoMetadata{ 850 Shape: shape, 851 SRID: srid, 852 }, 853 }} 854 } 855 856 // MakeGeography constructs a new instance of a geography-related type. 857 func MakeGeography(shape geopb.Shape, srid geopb.SRID) *T { 858 return &T{InternalType: InternalType{ 859 Family: GeographyFamily, 860 Oid: oidext.T_geography, 861 Locale: &emptyLocale, 862 GeoMetadata: &GeoMetadata{ 863 Shape: shape, 864 SRID: srid, 865 }, 866 }} 867 } 868 869 // GeoMetadata returns the GeoMetadata of the type object if it exists. 870 // This should only exist on Geometry and Geography types. 871 func (t *T) GeoMetadata() (*GeoMetadata, error) { 872 if t.InternalType.GeoMetadata == nil { 873 return nil, errors.Newf("GeoMetadata does not exist on type") 874 } 875 return t.InternalType.GeoMetadata, nil 876 } 877 878 var ( 879 // DefaultIntervalTypeMetadata returns a duration field that is unset, 880 // using INTERVAL or INTERVAL ( iconst32 ) syntax instead of INTERVAL 881 // with a qualifier afterwards. 882 DefaultIntervalTypeMetadata = IntervalTypeMetadata{} 883 ) 884 885 // IntervalTypeMetadata is metadata pertinent for intervals. 886 type IntervalTypeMetadata struct { 887 // DurationField represents the duration field definition. 888 DurationField IntervalDurationField 889 // Precision is the precision to use - note this matches InternalType rules. 890 Precision int32 891 // PrecisionIsSet indicates whether Precision is explicitly set. 892 PrecisionIsSet bool 893 } 894 895 // IsMinuteToSecond returns whether the IntervalDurationField represents 896 // the MINUTE TO SECOND interval qualifier. 897 func (m *IntervalDurationField) IsMinuteToSecond() bool { 898 return m.FromDurationType == IntervalDurationType_MINUTE && 899 m.DurationType == IntervalDurationType_SECOND 900 } 901 902 // IsDayToHour returns whether the IntervalDurationField represents 903 // the DAY TO HOUR interval qualifier. 904 func (m *IntervalDurationField) IsDayToHour() bool { 905 return m.FromDurationType == IntervalDurationType_DAY && 906 m.DurationType == IntervalDurationType_HOUR 907 } 908 909 // IntervalTypeMetadata returns the IntervalTypeMetadata for interval types. 910 func (t *T) IntervalTypeMetadata() (IntervalTypeMetadata, error) { 911 if t.Family() != IntervalFamily { 912 return IntervalTypeMetadata{}, errors.Newf("cannot call IntervalTypeMetadata on non-intervals") 913 } 914 return IntervalTypeMetadata{ 915 DurationField: *t.InternalType.IntervalDurationField, 916 Precision: t.InternalType.Precision, 917 PrecisionIsSet: t.InternalType.TimePrecisionIsSet, 918 }, nil 919 } 920 921 // MakeInterval constructs a new instance of a 922 // INTERVAL type (oid = T_interval) with a duration field. 923 // 924 // To use the default precision and field, use the `Interval` variable. 925 func MakeInterval(itm IntervalTypeMetadata) *T { 926 switch itm.DurationField.DurationType { 927 case IntervalDurationType_SECOND, IntervalDurationType_UNSET: 928 default: 929 if itm.PrecisionIsSet { 930 panic(errors.Errorf("cannot set precision for duration type %s", itm.DurationField.DurationType)) 931 } 932 } 933 if itm.Precision > 0 && !itm.PrecisionIsSet { 934 panic(errors.Errorf("precision must be set if Precision > 0")) 935 } 936 937 return &T{InternalType: InternalType{ 938 Family: IntervalFamily, 939 Oid: oid.T_interval, 940 Locale: &emptyLocale, 941 Precision: itm.Precision, 942 TimePrecisionIsSet: itm.PrecisionIsSet, 943 IntervalDurationField: &itm.DurationField, 944 }} 945 } 946 947 // MakeTimestamp constructs a new instance of a TIMESTAMP type that has at most 948 // the given number of fractional second digits. 949 // 950 // To use the default precision, use the `Timestamp` variable. 951 func MakeTimestamp(precision int32) *T { 952 return &T{InternalType: InternalType{ 953 Family: TimestampFamily, 954 Oid: oid.T_timestamp, 955 Precision: precision, 956 TimePrecisionIsSet: true, 957 Locale: &emptyLocale, 958 }} 959 } 960 961 // MakeTimestampTZ constructs a new instance of a TIMESTAMPTZ type that has at 962 // most the given number of fractional second digits. 963 // 964 // To use the default precision, use the `TimestampTZ` variable. 965 func MakeTimestampTZ(precision int32) *T { 966 return &T{InternalType: InternalType{ 967 Family: TimestampTZFamily, 968 Oid: oid.T_timestamptz, 969 Precision: precision, 970 TimePrecisionIsSet: true, 971 Locale: &emptyLocale, 972 }} 973 } 974 975 // MakeEnum constructs a new instance of an EnumFamily type with the given 976 // stable type ID. Note that it does not hydrate cached fields on the type. 977 func MakeEnum(typeID, arrayTypeID uint32) *T { 978 return &T{InternalType: InternalType{ 979 Family: EnumFamily, 980 Oid: StableTypeIDToOID(typeID), 981 Locale: &emptyLocale, 982 UDTMetadata: &PersistentUserDefinedTypeMetadata{ 983 StableTypeID: typeID, 984 StableArrayTypeID: arrayTypeID, 985 }, 986 }} 987 } 988 989 // MakeArray constructs a new instance of an ArrayFamily type with the given 990 // element type (which may itself be an ArrayFamily type). 991 func MakeArray(typ *T) *T { 992 arr := &T{InternalType: InternalType{ 993 Family: ArrayFamily, 994 Oid: calcArrayOid(typ), 995 ArrayContents: typ, 996 Locale: &emptyLocale, 997 }} 998 if typ.UserDefined() { 999 // If the element type is user defined, then the array type is user 1000 // defined as well, with a stable ID equal to the element's array type ID. 1001 arr.InternalType.UDTMetadata = &PersistentUserDefinedTypeMetadata{ 1002 StableTypeID: typ.StableArrayTypeID(), 1003 } 1004 } 1005 return arr 1006 } 1007 1008 // MakeTuple constructs a new instance of a TupleFamily type with the given 1009 // field types (some/all of which may be other TupleFamily types). 1010 // 1011 // Warning: the contents slice is used directly; the caller should not modify it 1012 // after calling this function. 1013 func MakeTuple(contents []*T) *T { 1014 return &T{InternalType: InternalType{ 1015 Family: TupleFamily, Oid: oid.T_record, TupleContents: contents, Locale: &emptyLocale, 1016 }} 1017 } 1018 1019 // MakeLabeledTuple constructs a new instance of a TupleFamily type with the 1020 // given field types and labels. 1021 func MakeLabeledTuple(contents []*T, labels []string) *T { 1022 if len(contents) != len(labels) && labels != nil { 1023 panic(errors.AssertionFailedf( 1024 "tuple contents and labels must be of same length: %v, %v", contents, labels)) 1025 } 1026 return &T{InternalType: InternalType{ 1027 Family: TupleFamily, 1028 Oid: oid.T_record, 1029 TupleContents: contents, 1030 TupleLabels: labels, 1031 Locale: &emptyLocale, 1032 }} 1033 } 1034 1035 // Family specifies a group of types that are compatible with one another. Types 1036 // in the same family can be compared, assigned, etc., but may differ from one 1037 // another in width, precision, locale, and other attributes. For example, it is 1038 // always an error to insert an INT value into a FLOAT column, because they are 1039 // not in the same family. However, values of different types within the same 1040 // family are "insert-compatible" with one another. Insertion may still result 1041 // in an error because of width overflow or other constraints, but it can at 1042 // least be attempted. 1043 // 1044 // Families are convenient for performing type switches on types, because in 1045 // most cases it is the type family that matters, not the specific type. For 1046 // example, when CRDB encodes values, it maintains routines for each family, 1047 // since types in the same family encode in very similar ways. 1048 // 1049 // Most type families have an associated "canonical type" that is the default 1050 // representative of that family, and which is a superset of all other types in 1051 // that family. Values with other types (in the same family) can always be 1052 // trivially converted to the canonical type with no loss of information. For 1053 // example, the canonical type for IntFamily is Int, which is a 64-bit integer. 1054 // Both 32-bit and 16-bit integers can be trivially converted to it. 1055 // 1056 // Execution operators and functions are permissive in terms of input (allow any 1057 // type within a given family), and typically return only values having 1058 // canonical types as output. For example, the IntFamily Plus operator allows 1059 // values having any IntFamily type as input. But then it will always convert 1060 // those values to 64-bit integers, and return a final 64-bit integer value 1061 // (types.Int). Doing this vastly reduces the required number of operator 1062 // overloads. 1063 func (t *T) Family() Family { 1064 return t.InternalType.Family 1065 } 1066 1067 // Oid returns the type's Postgres Object ID. The OID identifies the type more 1068 // specifically than the type family, and is used by the Postgres wire protocol 1069 // various Postgres catalog tables, functions like pg_typeof, etc. Maintaining 1070 // the OID is required for Postgres-compatibility. 1071 func (t *T) Oid() oid.Oid { 1072 return t.InternalType.Oid 1073 } 1074 1075 // Locale identifies a specific geographical, political, or cultural region that 1076 // impacts various character-based operations such as sorting, pattern matching, 1077 // and builtin functions like lower and upper. It is only defined for the 1078 // types in the CollatedStringFamily, and is the empty string for all other 1079 // types. 1080 func (t *T) Locale() string { 1081 return *t.InternalType.Locale 1082 } 1083 1084 // Width is the size or scale of the type, such as number of bits or characters. 1085 // 1086 // INT : # of bits (64, 32, 16) 1087 // FLOAT : # of bits (64, 32) 1088 // DECIMAL : max # of digits after decimal point (must be <= Precision) 1089 // STRING : max # of characters 1090 // COLLATEDSTRING: max # of characters 1091 // BIT : max # of bits 1092 // 1093 // Width is always 0 for other types. 1094 func (t *T) Width() int32 { 1095 return t.InternalType.Width 1096 } 1097 1098 // Precision is the accuracy of the data type. 1099 // 1100 // DECIMAL : max # digits (must be >= Width/Scale) 1101 // INTERVAL : max # fractional second digits 1102 // TIME : max # fractional second digits 1103 // TIMETZ : max # fractional second digits 1104 // TIMESTAMP : max # fractional second digits 1105 // TIMESTAMPTZ: max # fractional second digits 1106 // 1107 // Precision for time-related families has special rules for 0 -- see 1108 // `precision_is_set` on the `InternalType` proto. 1109 // 1110 // Precision is always 0 for other types. 1111 func (t *T) Precision() int32 { 1112 switch t.InternalType.Family { 1113 case IntervalFamily, TimestampFamily, TimestampTZFamily, TimeFamily, TimeTZFamily: 1114 if t.InternalType.Precision == 0 && !t.InternalType.TimePrecisionIsSet { 1115 return defaultTimePrecision 1116 } 1117 } 1118 return t.InternalType.Precision 1119 } 1120 1121 // TypeModifier returns the type modifier of the type. This corresponds to the 1122 // pg_attribute.atttypmod column. atttypmod records type-specific data supplied 1123 // at table creation time (for example, the maximum length of a varchar column). 1124 // The value will be -1 for types that do not need atttypmod. 1125 func (t *T) TypeModifier() int32 { 1126 typeModifier := int32(-1) 1127 if width := t.Width(); width != 0 { 1128 switch t.Family() { 1129 case StringFamily: 1130 // Postgres adds 4 to the attypmod for bounded string types, the 1131 // var header size. 1132 typeModifier = width + 4 1133 case BitFamily: 1134 typeModifier = width 1135 case DecimalFamily: 1136 // attTypMod is calculated by putting the precision in the upper 1137 // bits and the scale in the lower bits of a 32-bit int, and adding 1138 // 4 (the var header size). We mock this for clients' sake. See 1139 // numeric.c. 1140 typeModifier = ((t.Precision() << 16) | width) + 4 1141 } 1142 } 1143 return typeModifier 1144 } 1145 1146 // Scale is an alias method for Width, used for clarity for types in 1147 // DecimalFamily. 1148 func (t *T) Scale() int32 { 1149 return t.InternalType.Width 1150 } 1151 1152 // ArrayContents returns the type of array elements. This is nil for types that 1153 // are not in the ArrayFamily. 1154 func (t *T) ArrayContents() *T { 1155 return t.InternalType.ArrayContents 1156 } 1157 1158 // TupleContents returns a slice containing the type of each tuple field. This 1159 // is nil for non-TupleFamily types. 1160 func (t *T) TupleContents() []*T { 1161 return t.InternalType.TupleContents 1162 } 1163 1164 // TupleLabels returns a slice containing the labels of each tuple field. This 1165 // is nil for types not in the TupleFamily, or if the tuple type does not 1166 // specify labels. 1167 func (t *T) TupleLabels() []string { 1168 return t.InternalType.TupleLabels 1169 } 1170 1171 // StableTypeID returns the stable ID of the TypeDescriptor that backs this 1172 // type. This function only returns non-zero data for user defined types. 1173 func (t *T) StableTypeID() uint32 { 1174 return t.InternalType.UDTMetadata.StableTypeID 1175 } 1176 1177 // StableArrayTypeID returns the stable ID of the TypeDescriptor that backs 1178 // the implicit array type for the type. This function only returns non-zero 1179 // data for user defined types that aren't array types. 1180 func (t *T) StableArrayTypeID() uint32 { 1181 return t.InternalType.UDTMetadata.StableArrayTypeID 1182 } 1183 1184 // UserDefined returns whether or not t is a user defined type. 1185 func (t *T) UserDefined() bool { 1186 return t.InternalType.UDTMetadata != nil 1187 } 1188 1189 var familyNames = map[Family]string{ 1190 AnyFamily: "any", 1191 ArrayFamily: "array", 1192 BitFamily: "bit", 1193 BoolFamily: "bool", 1194 BytesFamily: "bytes", 1195 CollatedStringFamily: "collatedstring", 1196 DateFamily: "date", 1197 DecimalFamily: "decimal", 1198 EnumFamily: "enum", 1199 FloatFamily: "float", 1200 GeographyFamily: "geography", 1201 GeometryFamily: "geometry", 1202 INetFamily: "inet", 1203 IntFamily: "int", 1204 IntervalFamily: "interval", 1205 JsonFamily: "jsonb", 1206 OidFamily: "oid", 1207 StringFamily: "string", 1208 TimeFamily: "time", 1209 TimestampFamily: "timestamp", 1210 TimestampTZFamily: "timestamptz", 1211 TimeTZFamily: "timetz", 1212 TupleFamily: "tuple", 1213 UnknownFamily: "unknown", 1214 UuidFamily: "uuid", 1215 } 1216 1217 // Name returns a user-friendly word indicating the family type. 1218 // 1219 // TODO(radu): investigate whether anything breaks if we use 1220 // enumvalue_customname and use String() instead. 1221 func (f Family) Name() string { 1222 ret, ok := familyNames[f] 1223 if !ok { 1224 panic(errors.AssertionFailedf("unexpected Family: %d", f)) 1225 } 1226 return ret 1227 } 1228 1229 // Name returns a single word description of the type that describes it 1230 // succinctly, but without all the details, such as width, locale, etc. The name 1231 // is sometimes the same as the name returned by SQLStandardName, but is more 1232 // CRDB friendly. 1233 // 1234 // TODO(andyk): Should these be changed to be the same as SQLStandardName? 1235 func (t *T) Name() string { 1236 switch fam := t.Family(); fam { 1237 case AnyFamily: 1238 return "anyelement" 1239 1240 case ArrayFamily: 1241 switch t.Oid() { 1242 case oid.T_oidvector: 1243 return "oidvector" 1244 case oid.T_int2vector: 1245 return "int2vector" 1246 } 1247 return t.ArrayContents().Name() + "[]" 1248 1249 case BitFamily: 1250 if t.Oid() == oid.T_varbit { 1251 return "varbit" 1252 } 1253 return "bit" 1254 1255 case FloatFamily: 1256 switch t.Width() { 1257 case 64: 1258 return "float" 1259 case 32: 1260 return "float4" 1261 default: 1262 panic(errors.AssertionFailedf("programming error: unknown float width: %d", t.Width())) 1263 } 1264 1265 case IntFamily: 1266 switch t.Width() { 1267 case 64: 1268 return "int" 1269 case 32: 1270 return "int4" 1271 case 16: 1272 return "int2" 1273 default: 1274 panic(errors.AssertionFailedf("programming error: unknown int width: %d", t.Width())) 1275 } 1276 1277 case OidFamily: 1278 return t.SQLStandardName() 1279 1280 case StringFamily, CollatedStringFamily: 1281 switch t.Oid() { 1282 case oid.T_text: 1283 return "string" 1284 case oid.T_bpchar: 1285 return "char" 1286 case oid.T_char: 1287 // Yes, that's the name. The ways of PostgreSQL are inscrutable. 1288 return `"char"` 1289 case oid.T_varchar: 1290 return "varchar" 1291 case oid.T_name: 1292 return "name" 1293 } 1294 panic(errors.AssertionFailedf("unexpected OID: %d", t.Oid())) 1295 1296 case TupleFamily: 1297 // Tuple types are currently anonymous, with no name. 1298 return "" 1299 1300 case EnumFamily: 1301 if t.Oid() == oid.T_anyenum { 1302 return "anyenum" 1303 } 1304 // This can be nil during unit testing. 1305 if t.TypeMeta.Name == nil { 1306 return "unknown_enum" 1307 } 1308 return t.TypeMeta.Name.Basename() 1309 1310 default: 1311 return fam.Name() 1312 } 1313 } 1314 1315 // PGName returns the Postgres name for the type. This is sometimes different 1316 // than the native CRDB name for it (i.e. the Name function). It is used when 1317 // compatibility with PG is important. Examples of differences: 1318 // 1319 // Name() PGName() 1320 // -------------------------- 1321 // char bpchar 1322 // "char" char 1323 // bytes bytea 1324 // int4[] _int4 1325 // 1326 func (t *T) PGName() string { 1327 name, ok := oidext.TypeName(t.Oid()) 1328 if ok { 1329 return strings.ToLower(name) 1330 } 1331 1332 // For user defined types, return the basename. 1333 if t.UserDefined() { 1334 return t.TypeMeta.Name.Basename() 1335 } 1336 1337 // Postgres does not have an UNKNOWN[] type. However, CRDB does, so 1338 // manufacture a name for it. 1339 if t.Family() != ArrayFamily || t.ArrayContents().Family() != UnknownFamily { 1340 panic(errors.AssertionFailedf("unknown PG name for oid %d", t.Oid())) 1341 } 1342 return "_unknown" 1343 } 1344 1345 // SQLStandardName returns the type's name as it is specified in the SQL 1346 // standard (or by Postgres for any non-standard types). This can be looked up 1347 // for any type in Postgres using a query similar to this: 1348 // 1349 // SELECT format_type(pg_typeof(1::int)::regtype, NULL) 1350 // 1351 func (t *T) SQLStandardName() string { 1352 return t.SQLStandardNameWithTypmod(false, 0) 1353 } 1354 1355 var telemetryNameReplaceRegex = regexp.MustCompile("[^a-zA-Z0-9]") 1356 1357 // TelemetryName returns a name that is friendly for telemetry. 1358 func (t *T) TelemetryName() string { 1359 return strings.ToLower(telemetryNameReplaceRegex.ReplaceAllString(t.SQLString(), "_")) 1360 } 1361 1362 // SQLStandardNameWithTypmod is like SQLStandardName but it also accepts a 1363 // typmod argument, and a boolean which indicates whether or not a typmod was 1364 // even specified. The expected results of this function should be, in Postgres: 1365 // 1366 // SELECT format_type('thetype'::regype, typmod) 1367 // 1368 // Generally, what this does with a non-0 typmod is append the scale, precision 1369 // or length of a datatype to the name of the datatype. For example, a 1370 // varchar(20) would appear as character varying(20) when provided the typmod 1371 // value for varchar(20), which happens to be 24. 1372 // 1373 // This function is full of special cases. See backend/utils/adt/format_type.c 1374 // in Postgres. 1375 func (t *T) SQLStandardNameWithTypmod(haveTypmod bool, typmod int) string { 1376 var buf strings.Builder 1377 switch t.Family() { 1378 case AnyFamily: 1379 return "anyelement" 1380 case ArrayFamily: 1381 switch t.Oid() { 1382 case oid.T_oidvector: 1383 return "oidvector" 1384 case oid.T_int2vector: 1385 return "int2vector" 1386 } 1387 return t.ArrayContents().SQLStandardName() + "[]" 1388 case BitFamily: 1389 if t.Oid() == oid.T_varbit { 1390 buf.WriteString("bit varying") 1391 } else { 1392 buf.WriteString("bit") 1393 } 1394 if !haveTypmod || typmod <= 0 { 1395 return buf.String() 1396 } 1397 buf.WriteString(fmt.Sprintf("(%d)", typmod)) 1398 return buf.String() 1399 case BoolFamily: 1400 return "boolean" 1401 case BytesFamily: 1402 return "bytea" 1403 case DateFamily: 1404 return "date" 1405 case DecimalFamily: 1406 if !haveTypmod || typmod <= 0 { 1407 return "numeric" 1408 } 1409 // The typmod of a numeric has the precision in the upper bits and the 1410 // scale in the lower bits of a 32-bit int, after subtracting 4 (the var 1411 // header size). See numeric.c. 1412 typmod -= 4 1413 return fmt.Sprintf( 1414 "numeric(%d,%d)", 1415 (typmod>>16)&0xffff, 1416 typmod&0xffff, 1417 ) 1418 1419 case FloatFamily: 1420 switch t.Width() { 1421 case 32: 1422 return "real" 1423 case 64: 1424 return "double precision" 1425 default: 1426 panic(errors.AssertionFailedf("programming error: unknown float width: %d", t.Width())) 1427 } 1428 case GeometryFamily, GeographyFamily: 1429 return t.Name() + t.InternalType.GeoMetadata.SQLString() 1430 case INetFamily: 1431 return "inet" 1432 case IntFamily: 1433 switch t.Width() { 1434 case 16: 1435 return "smallint" 1436 case 32: 1437 // PG shows "integer" for int4. 1438 return "integer" 1439 case 64: 1440 return "bigint" 1441 default: 1442 panic(errors.AssertionFailedf("programming error: unknown int width: %d", t.Width())) 1443 } 1444 case IntervalFamily: 1445 // TODO(jordan): intervals can have typmods, but we don't support them in the same way. 1446 // Masking is used to extract the precision (src/include/utils/timestamp.h), whereas 1447 // we store it as `IntervalDurationField`. 1448 return "interval" 1449 case JsonFamily: 1450 // Only binary JSON is currently supported. 1451 return "jsonb" 1452 case OidFamily: 1453 switch t.Oid() { 1454 case oid.T_oid: 1455 return "oid" 1456 case oid.T_regclass: 1457 return "regclass" 1458 case oid.T_regnamespace: 1459 return "regnamespace" 1460 case oid.T_regproc: 1461 return "regproc" 1462 case oid.T_regprocedure: 1463 return "regprocedure" 1464 case oid.T_regtype: 1465 return "regtype" 1466 default: 1467 panic(errors.AssertionFailedf("unexpected Oid: %v", errors.Safe(t.Oid()))) 1468 } 1469 case StringFamily, CollatedStringFamily: 1470 switch t.Oid() { 1471 case oid.T_text: 1472 buf.WriteString("text") 1473 case oid.T_varchar: 1474 buf.WriteString("character varying") 1475 case oid.T_bpchar: 1476 if haveTypmod && typmod < 0 { 1477 // Special case. Run `select format_type('bpchar'::regtype, -1);` in pg. 1478 return "bpchar" 1479 } 1480 buf.WriteString("character") 1481 case oid.T_char: 1482 // Type modifiers not allowed for "char". 1483 return `"char"` 1484 case oid.T_name: 1485 // Type modifiers not allowed for name. 1486 return "name" 1487 default: 1488 panic(errors.AssertionFailedf("unexpected OID: %d", t.Oid())) 1489 } 1490 if !haveTypmod { 1491 return buf.String() 1492 } 1493 1494 // Typmod gets subtracted by 4 for all non-text string-like types to produce 1495 // the length. 1496 if t.Oid() != oid.T_text { 1497 typmod -= 4 1498 } 1499 if typmod <= 0 { 1500 // In this case, we don't print any modifier. 1501 return buf.String() 1502 } 1503 buf.WriteString(fmt.Sprintf("(%d)", typmod)) 1504 return buf.String() 1505 1506 case TimeFamily: 1507 if !haveTypmod || typmod < 0 { 1508 return "time without time zone" 1509 } 1510 return fmt.Sprintf("time(%d) without time zone", typmod) 1511 case TimeTZFamily: 1512 if !haveTypmod || typmod < 0 { 1513 return "time with time zone" 1514 } 1515 return fmt.Sprintf("time(%d) with time zone", typmod) 1516 case TimestampFamily: 1517 if !haveTypmod || typmod < 0 { 1518 return "timestamp without time zone" 1519 } 1520 return fmt.Sprintf("timestamp(%d) without time zone", typmod) 1521 case TimestampTZFamily: 1522 if !haveTypmod || typmod < 0 { 1523 return "timestamp with time zone" 1524 } 1525 return fmt.Sprintf("timestamp(%d) with time zone", typmod) 1526 case TupleFamily: 1527 return "record" 1528 case UnknownFamily: 1529 return "unknown" 1530 case UuidFamily: 1531 return "uuid" 1532 case EnumFamily: 1533 return t.TypeMeta.Name.FQName() 1534 default: 1535 panic(errors.AssertionFailedf("unexpected Family: %v", errors.Safe(t.Family()))) 1536 } 1537 } 1538 1539 // InformationSchemaName returns the string suitable to populate the data_type 1540 // column of information_schema.columns. 1541 // 1542 // This is different from SQLString() in that it must report SQL standard names 1543 // that are compatible with PostgreSQL client expectations. 1544 func (t *T) InformationSchemaName() string { 1545 // This is the same as SQLStandardName, except for the case of arrays. 1546 if t.Family() == ArrayFamily { 1547 return "ARRAY" 1548 } 1549 return t.SQLStandardName() 1550 } 1551 1552 // SQLString returns the CockroachDB native SQL string that can be used to 1553 // reproduce the type via parsing the string as a type. It is used in error 1554 // messages and also to produce the output of SHOW CREATE. 1555 func (t *T) SQLString() string { 1556 switch t.Family() { 1557 case BitFamily: 1558 o := t.Oid() 1559 typName := "BIT" 1560 if o == oid.T_varbit { 1561 typName = "VARBIT" 1562 } 1563 // BIT(1) pretty-prints as just BIT. 1564 if (o != oid.T_varbit && t.Width() > 1) || 1565 (o == oid.T_varbit && t.Width() > 0) { 1566 typName = fmt.Sprintf("%s(%d)", typName, t.Width()) 1567 } 1568 return typName 1569 case IntFamily: 1570 switch t.Width() { 1571 case 16: 1572 return "INT2" 1573 case 32: 1574 return "INT4" 1575 case 64: 1576 return "INT8" 1577 default: 1578 panic(errors.AssertionFailedf("programming error: unknown int width: %d", t.Width())) 1579 } 1580 case StringFamily: 1581 return t.stringTypeSQL() 1582 case CollatedStringFamily: 1583 return t.collatedStringTypeSQL(false /* isArray */) 1584 case FloatFamily: 1585 const realName = "FLOAT4" 1586 const doubleName = "FLOAT8" 1587 if t.Width() == 32 { 1588 return realName 1589 } 1590 return doubleName 1591 case DecimalFamily: 1592 if t.Precision() > 0 { 1593 if t.Width() > 0 { 1594 return fmt.Sprintf("DECIMAL(%d,%d)", t.Precision(), t.Scale()) 1595 } 1596 return fmt.Sprintf("DECIMAL(%d)", t.Precision()) 1597 } 1598 case JsonFamily: 1599 // Only binary JSON is currently supported. 1600 return "JSONB" 1601 case TimestampFamily, TimestampTZFamily, TimeFamily, TimeTZFamily: 1602 if t.InternalType.Precision > 0 || t.InternalType.TimePrecisionIsSet { 1603 return fmt.Sprintf("%s(%d)", strings.ToUpper(t.Name()), t.Precision()) 1604 } 1605 case GeometryFamily, GeographyFamily: 1606 return strings.ToUpper(t.Name() + t.InternalType.GeoMetadata.SQLString()) 1607 case IntervalFamily: 1608 switch t.InternalType.IntervalDurationField.DurationType { 1609 case IntervalDurationType_UNSET: 1610 if t.InternalType.Precision > 0 || t.InternalType.TimePrecisionIsSet { 1611 return fmt.Sprintf("%s(%d)", strings.ToUpper(t.Name()), t.Precision()) 1612 } 1613 default: 1614 fromStr := "" 1615 if t.InternalType.IntervalDurationField.FromDurationType != IntervalDurationType_UNSET { 1616 fromStr = fmt.Sprintf("%s TO ", t.InternalType.IntervalDurationField.FromDurationType.String()) 1617 } 1618 precisionStr := "" 1619 if t.InternalType.Precision > 0 || t.InternalType.TimePrecisionIsSet { 1620 precisionStr = fmt.Sprintf("(%d)", t.Precision()) 1621 } 1622 return fmt.Sprintf( 1623 "%s %s%s%s", 1624 strings.ToUpper(t.Name()), 1625 fromStr, 1626 t.InternalType.IntervalDurationField.DurationType.String(), 1627 precisionStr, 1628 ) 1629 } 1630 case OidFamily: 1631 if name, ok := oidext.TypeName(t.Oid()); ok { 1632 return name 1633 } 1634 case ArrayFamily: 1635 switch t.Oid() { 1636 case oid.T_oidvector: 1637 return "OIDVECTOR" 1638 case oid.T_int2vector: 1639 return "INT2VECTOR" 1640 } 1641 if t.ArrayContents().Family() == CollatedStringFamily { 1642 return t.ArrayContents().collatedStringTypeSQL(true /* isArray */) 1643 } 1644 return t.ArrayContents().SQLString() + "[]" 1645 case EnumFamily: 1646 if t.Oid() == oid.T_anyenum { 1647 return "anyenum" 1648 } 1649 return t.TypeMeta.Name.FQName() 1650 } 1651 return strings.ToUpper(t.Name()) 1652 } 1653 1654 // Equivalent returns true if this type is "equivalent" to the given type. 1655 // Equivalent types are compatible with one another: they can be compared, 1656 // assigned, and unioned. Equivalent types must always have the same type family 1657 // for the root type and any descendant types (i.e. in case of array or tuple 1658 // types). Types in the CollatedStringFamily must have the same locale. But 1659 // other attributes of equivalent types, such as width, precision, and oid, can 1660 // be different. 1661 // 1662 // Wildcard types (e.g. Any, AnyArray, AnyTuple, etc) have special equivalence 1663 // behavior. AnyFamily types match any other type, including other AnyFamily 1664 // types. And a wildcard collation (empty string) matches any other collation. 1665 func (t *T) Equivalent(other *T) bool { 1666 if t.Family() == AnyFamily || other.Family() == AnyFamily { 1667 return true 1668 } 1669 if t.Family() != other.Family() { 1670 return false 1671 } 1672 1673 switch t.Family() { 1674 case CollatedStringFamily: 1675 if t.Locale() != "" && other.Locale() != "" && t.Locale() != other.Locale() { 1676 return false 1677 } 1678 1679 case TupleFamily: 1680 // If either tuple is the wildcard tuple, it's equivalent to any other 1681 // tuple type. This allows overloads to specify that they take an arbitrary 1682 // tuple type. 1683 if IsWildcardTupleType(t) || IsWildcardTupleType(other) { 1684 return true 1685 } 1686 if len(t.TupleContents()) != len(other.TupleContents()) { 1687 return false 1688 } 1689 for i := range t.TupleContents() { 1690 if !t.TupleContents()[i].Equivalent(other.TupleContents()[i]) { 1691 return false 1692 } 1693 } 1694 1695 case ArrayFamily: 1696 if !t.ArrayContents().Equivalent(other.ArrayContents()) { 1697 return false 1698 } 1699 1700 case EnumFamily: 1701 // If one of the types is anyenum, then allow the comparison to 1702 // go through -- anyenum is used when matching overloads. 1703 if t.Oid() == oid.T_anyenum || other.Oid() == oid.T_anyenum { 1704 return true 1705 } 1706 if t.StableTypeID() != other.StableTypeID() { 1707 return false 1708 } 1709 } 1710 1711 return true 1712 } 1713 1714 // Identical returns true if every field in this ColumnType is exactly the same 1715 // as every corresponding field in the given ColumnType. Identical performs a 1716 // deep comparison, traversing any Tuple or Array contents. 1717 // 1718 // NOTE: Consider whether the desired semantics really require identical types, 1719 // or if Equivalent is the right method to call instead. 1720 func (t *T) Identical(other *T) bool { 1721 return t.InternalType.Identical(&other.InternalType) 1722 } 1723 1724 // Equal is for use in generated protocol buffer code only. 1725 func (t *T) Equal(other *T) bool { 1726 return t.Identical(other) 1727 } 1728 1729 // Size returns the size, in bytes, of this type once it has been marshaled to 1730 // a byte buffer. This is typically called to determine the size of the buffer 1731 // that needs to be allocated before calling Marshal. 1732 // 1733 // Marshal is part of the protoutil.Message interface. 1734 func (t *T) Size() (n int) { 1735 // Need to first downgrade the type before delegating to InternalType, 1736 // because Marshal will downgrade. 1737 temp := *t 1738 err := temp.downgradeType() 1739 if err != nil { 1740 panic(errors.AssertionFailedf("error during Size call: %v", err)) 1741 } 1742 return temp.InternalType.Size() 1743 } 1744 1745 // Identical is the internal implementation for T.Identical. See that comment 1746 // for details. 1747 func (t *InternalType) Identical(other *InternalType) bool { 1748 if t.Family != other.Family { 1749 return false 1750 } 1751 if t.Width != other.Width { 1752 return false 1753 } 1754 if t.Precision != other.Precision { 1755 return false 1756 } 1757 if t.TimePrecisionIsSet != other.TimePrecisionIsSet { 1758 return false 1759 } 1760 if t.IntervalDurationField != nil && other.IntervalDurationField != nil { 1761 if *t.IntervalDurationField != *other.IntervalDurationField { 1762 return false 1763 } 1764 } else if t.IntervalDurationField != nil { 1765 return false 1766 } else if other.IntervalDurationField != nil { 1767 return false 1768 } 1769 if t.GeoMetadata != nil && other.GeoMetadata != nil { 1770 if t.GeoMetadata.Shape != other.GeoMetadata.Shape { 1771 return false 1772 } 1773 if t.GeoMetadata.SRID != other.GeoMetadata.SRID { 1774 return false 1775 } 1776 } else if t.GeoMetadata != nil { 1777 return false 1778 } else if other.GeoMetadata != nil { 1779 return false 1780 } 1781 if t.Locale != nil && other.Locale != nil { 1782 if *t.Locale != *other.Locale { 1783 return false 1784 } 1785 } else if t.Locale != nil { 1786 return false 1787 } else if other.Locale != nil { 1788 return false 1789 } 1790 if t.ArrayContents != nil && other.ArrayContents != nil { 1791 if !t.ArrayContents.Identical(other.ArrayContents) { 1792 return false 1793 } 1794 } else if t.ArrayContents != nil { 1795 return false 1796 } else if other.ArrayContents != nil { 1797 return false 1798 } 1799 if len(t.TupleContents) != len(other.TupleContents) { 1800 return false 1801 } 1802 for i := range t.TupleContents { 1803 if !t.TupleContents[i].Identical(other.TupleContents[i]) { 1804 return false 1805 } 1806 } 1807 if len(t.TupleLabels) != len(other.TupleLabels) { 1808 return false 1809 } 1810 for i := range t.TupleLabels { 1811 if t.TupleLabels[i] != other.TupleLabels[i] { 1812 return false 1813 } 1814 } 1815 if t.UDTMetadata != nil && other.UDTMetadata != nil { 1816 if t.UDTMetadata.StableTypeID != other.UDTMetadata.StableTypeID { 1817 return false 1818 } 1819 if t.UDTMetadata.StableArrayTypeID != other.UDTMetadata.StableArrayTypeID { 1820 return false 1821 } 1822 } else if t.UDTMetadata != nil { 1823 return false 1824 } else if other.UDTMetadata != nil { 1825 return false 1826 } 1827 return t.Oid == other.Oid 1828 } 1829 1830 // Unmarshal deserializes a type from the given byte representation using gogo 1831 // protobuf serialization rules. It is backwards-compatible with formats used 1832 // by older versions of CRDB. 1833 // 1834 // var t T 1835 // err := protoutil.Unmarshal(data, &t) 1836 // 1837 // Unmarshal is part of the protoutil.Message interface. 1838 func (t *T) Unmarshal(data []byte) error { 1839 // Unmarshal the internal type, and then perform an upgrade step to convert 1840 // to the latest format. 1841 err := protoutil.Unmarshal(data, &t.InternalType) 1842 if err != nil { 1843 return err 1844 } 1845 return t.upgradeType() 1846 } 1847 1848 // upgradeType assumes its input was just unmarshaled from bytes that may have 1849 // been serialized by any previous version of CRDB. It upgrades the object 1850 // according to the requirements of the latest version by remapping fields and 1851 // setting required values. This is necessary to preserve backwards- 1852 // compatibility with older formats (e.g. restoring database from old backup). 1853 func (t *T) upgradeType() error { 1854 switch t.Family() { 1855 case IntFamily: 1856 // Check VisibleType field that was populated in previous versions. 1857 switch t.InternalType.VisibleType { 1858 case visibleSMALLINT: 1859 t.InternalType.Width = 16 1860 t.InternalType.Oid = oid.T_int2 1861 case visibleINTEGER: 1862 t.InternalType.Width = 32 1863 t.InternalType.Oid = oid.T_int4 1864 case visibleBIGINT: 1865 t.InternalType.Width = 64 1866 t.InternalType.Oid = oid.T_int8 1867 case visibleBIT, visibleNONE: 1868 // Pre-2.1 BIT was using IntFamily with arbitrary widths. Clamp them 1869 // to fixed/known widths. See #34161. 1870 switch t.Width() { 1871 case 16: 1872 t.InternalType.Oid = oid.T_int2 1873 case 32: 1874 t.InternalType.Oid = oid.T_int4 1875 default: 1876 // Assume INT8 if width is 0 or not valid. 1877 t.InternalType.Oid = oid.T_int8 1878 t.InternalType.Width = 64 1879 } 1880 default: 1881 return errors.AssertionFailedf("unexpected visible type: %d", t.InternalType.VisibleType) 1882 } 1883 1884 case FloatFamily: 1885 // Map visible REAL type to 32-bit width. 1886 switch t.InternalType.VisibleType { 1887 case visibleREAL: 1888 t.InternalType.Oid = oid.T_float4 1889 t.InternalType.Width = 32 1890 case visibleDOUBLE: 1891 t.InternalType.Oid = oid.T_float8 1892 t.InternalType.Width = 64 1893 case visibleNONE: 1894 switch t.Width() { 1895 case 32: 1896 t.InternalType.Oid = oid.T_float4 1897 case 64: 1898 t.InternalType.Oid = oid.T_float8 1899 default: 1900 // Pre-2.1 (before Width) there were 3 cases: 1901 // - VisibleType = DOUBLE PRECISION, Width = 0 -> now clearly FLOAT8 1902 // - VisibleType = NONE, Width = 0 -> now clearly FLOAT8 1903 // - VisibleType = NONE, Precision > 0 -> we need to derive the width. 1904 if t.Precision() >= 1 && t.Precision() <= 24 { 1905 t.InternalType.Oid = oid.T_float4 1906 t.InternalType.Width = 32 1907 } else { 1908 t.InternalType.Oid = oid.T_float8 1909 t.InternalType.Width = 64 1910 } 1911 } 1912 default: 1913 return errors.AssertionFailedf("unexpected visible type: %d", t.InternalType.VisibleType) 1914 } 1915 1916 // Precision should always be set to 0 going forward. 1917 t.InternalType.Precision = 0 1918 1919 case TimestampFamily, TimestampTZFamily, TimeFamily, TimeTZFamily: 1920 // Some bad/experimental versions of master had precision stored as `-1`. 1921 // This represented a default - so upgrade this to 0 with TimePrecisionIsSet = false. 1922 if t.InternalType.Precision == -1 { 1923 t.InternalType.Precision = 0 1924 t.InternalType.TimePrecisionIsSet = false 1925 } 1926 // Going forwards after 19.2, we want `TimePrecisionIsSet` to be explicitly set 1927 // if Precision is > 0. 1928 if t.InternalType.Precision > 0 { 1929 t.InternalType.TimePrecisionIsSet = true 1930 } 1931 case IntervalFamily: 1932 // Fill in the IntervalDurationField here. 1933 if t.InternalType.IntervalDurationField == nil { 1934 t.InternalType.IntervalDurationField = &IntervalDurationField{} 1935 } 1936 // Going forwards after 19.2, we want `TimePrecisionIsSet` to be explicitly set 1937 // if Precision is > 0. 1938 if t.InternalType.Precision > 0 { 1939 t.InternalType.TimePrecisionIsSet = true 1940 } 1941 case StringFamily, CollatedStringFamily: 1942 // Map string-related visible types to corresponding Oid values. 1943 switch t.InternalType.VisibleType { 1944 case visibleVARCHAR: 1945 t.InternalType.Oid = oid.T_varchar 1946 case visibleCHAR: 1947 t.InternalType.Oid = oid.T_bpchar 1948 case visibleQCHAR: 1949 t.InternalType.Oid = oid.T_char 1950 case visibleNONE: 1951 t.InternalType.Oid = oid.T_text 1952 default: 1953 return errors.AssertionFailedf("unexpected visible type: %d", t.InternalType.VisibleType) 1954 } 1955 if t.InternalType.Family == StringFamily { 1956 if t.InternalType.Locale != nil && len(*t.InternalType.Locale) != 0 { 1957 return errors.AssertionFailedf( 1958 "STRING type should not have locale: %s", *t.InternalType.Locale) 1959 } 1960 } 1961 1962 case BitFamily: 1963 // Map visible VARBIT type to T_varbit OID value. 1964 switch t.InternalType.VisibleType { 1965 case visibleVARBIT: 1966 t.InternalType.Oid = oid.T_varbit 1967 case visibleNONE: 1968 t.InternalType.Oid = oid.T_bit 1969 default: 1970 return errors.AssertionFailedf("unexpected visible type: %d", t.InternalType.VisibleType) 1971 } 1972 1973 case ArrayFamily: 1974 if t.ArrayContents() == nil { 1975 // This array type was serialized by a previous version of CRDB, 1976 // so construct the array contents from scratch. 1977 arrayContents := *t 1978 arrayContents.InternalType.Family = *t.InternalType.ArrayElemType 1979 arrayContents.InternalType.ArrayDimensions = nil 1980 arrayContents.InternalType.ArrayElemType = nil 1981 if err := arrayContents.upgradeType(); err != nil { 1982 return err 1983 } 1984 t.InternalType.ArrayContents = &arrayContents 1985 t.InternalType.Oid = calcArrayOid(t.ArrayContents()) 1986 } 1987 1988 // Marshaling/unmarshaling nested arrays is not yet supported. 1989 if t.ArrayContents().Family() == ArrayFamily { 1990 return errors.AssertionFailedf("nested array should never be unmarshaled") 1991 } 1992 1993 // Zero out fields that may have been used to store information about 1994 // the array element type, or which are no longer in use. 1995 t.InternalType.Width = 0 1996 t.InternalType.Precision = 0 1997 t.InternalType.Locale = nil 1998 t.InternalType.VisibleType = 0 1999 t.InternalType.ArrayElemType = nil 2000 t.InternalType.ArrayDimensions = nil 2001 2002 case int2vector: 2003 t.InternalType.Family = ArrayFamily 2004 t.InternalType.Width = 0 2005 t.InternalType.Oid = oid.T_int2vector 2006 t.InternalType.ArrayContents = Int2 2007 2008 case oidvector: 2009 t.InternalType.Family = ArrayFamily 2010 t.InternalType.Oid = oid.T_oidvector 2011 t.InternalType.ArrayContents = Oid 2012 2013 case name: 2014 if t.InternalType.Locale != nil { 2015 t.InternalType.Family = CollatedStringFamily 2016 } else { 2017 t.InternalType.Family = StringFamily 2018 } 2019 t.InternalType.Oid = oid.T_name 2020 if t.Width() != 0 { 2021 return errors.AssertionFailedf("name type cannot have non-zero width: %d", t.Width()) 2022 } 2023 } 2024 2025 if t.InternalType.Oid == 0 { 2026 t.InternalType.Oid = familyToOid[t.Family()] 2027 } 2028 2029 // Clear the deprecated visible types, since they are now handled by the 2030 // Width or Oid fields. 2031 t.InternalType.VisibleType = 0 2032 2033 // If locale is not set, always set it to the empty string, in order to avoid 2034 // bothersome deref errors when the Locale method is called. 2035 if t.InternalType.Locale == nil { 2036 t.InternalType.Locale = &emptyLocale 2037 } 2038 2039 return nil 2040 } 2041 2042 // Marshal serializes a type into a byte representation using gogo protobuf 2043 // serialization rules. It returns the resulting bytes as a slice. The bytes 2044 // are serialized in a format that is backwards-compatible with the previous 2045 // version of CRDB so that clusters can run in mixed version mode during 2046 // upgrade. 2047 // 2048 // bytes, err := protoutil.Marshal(&typ) 2049 // 2050 func (t *T) Marshal() (data []byte, err error) { 2051 // First downgrade to a struct that will be serialized in a backwards- 2052 // compatible bytes format. 2053 temp := *t 2054 if err := temp.downgradeType(); err != nil { 2055 return nil, err 2056 } 2057 return protoutil.Marshal(&temp.InternalType) 2058 } 2059 2060 // MarshalTo behaves like Marshal, except that it deserializes to an existing 2061 // byte slice and returns the number of bytes written to it. The slice must 2062 // already have sufficient capacity. Callers can use the Size method to 2063 // determine how much capacity needs to be allocated. 2064 // 2065 // Marshal is part of the protoutil.Message interface. 2066 func (t *T) MarshalTo(data []byte) (int, error) { 2067 temp := *t 2068 if err := temp.downgradeType(); err != nil { 2069 return 0, err 2070 } 2071 return temp.InternalType.MarshalTo(data) 2072 } 2073 2074 // of the latest CRDB version. It updates the fields so that they will be 2075 // marshaled into a format that is compatible with the previous version of 2076 // CRDB. This is necessary to preserve backwards-compatibility in mixed-version 2077 // scenarios, such as during upgrade. 2078 func (t *T) downgradeType() error { 2079 // Set Family and VisibleType for 19.1 backwards-compatibility. 2080 switch t.Family() { 2081 case BitFamily: 2082 if t.Oid() == oid.T_varbit { 2083 t.InternalType.VisibleType = visibleVARBIT 2084 } 2085 2086 case FloatFamily: 2087 switch t.Width() { 2088 case 32: 2089 t.InternalType.VisibleType = visibleREAL 2090 } 2091 2092 case StringFamily, CollatedStringFamily: 2093 switch t.Oid() { 2094 case oid.T_text: 2095 // Nothing to do. 2096 case oid.T_varchar: 2097 t.InternalType.VisibleType = visibleVARCHAR 2098 case oid.T_bpchar: 2099 t.InternalType.VisibleType = visibleCHAR 2100 case oid.T_char: 2101 t.InternalType.VisibleType = visibleQCHAR 2102 case oid.T_name: 2103 t.InternalType.Family = name 2104 default: 2105 return errors.AssertionFailedf("unexpected Oid: %d", t.Oid()) 2106 } 2107 2108 case ArrayFamily: 2109 // Marshaling/unmarshaling nested arrays is not yet supported. 2110 if t.ArrayContents().Family() == ArrayFamily { 2111 return errors.AssertionFailedf("nested array should never be marshaled") 2112 } 2113 2114 // Downgrade to array representation used before 19.2, in which the array 2115 // type fields specified the width, locale, etc. of the element type. 2116 temp := *t.InternalType.ArrayContents 2117 if err := temp.downgradeType(); err != nil { 2118 return err 2119 } 2120 t.InternalType.Width = temp.InternalType.Width 2121 t.InternalType.Precision = temp.InternalType.Precision 2122 t.InternalType.Locale = temp.InternalType.Locale 2123 t.InternalType.VisibleType = temp.InternalType.VisibleType 2124 t.InternalType.ArrayElemType = &t.InternalType.ArrayContents.InternalType.Family 2125 2126 switch t.Oid() { 2127 case oid.T_int2vector: 2128 t.InternalType.Family = int2vector 2129 case oid.T_oidvector: 2130 t.InternalType.Family = oidvector 2131 } 2132 } 2133 2134 // Map empty locale to nil. 2135 if t.InternalType.Locale != nil && len(*t.InternalType.Locale) == 0 { 2136 t.InternalType.Locale = nil 2137 } 2138 2139 return nil 2140 } 2141 2142 // String returns the name of the type, similar to the Name method. However, it 2143 // expands CollatedStringFamily, ArrayFamily, and TupleFamily types to be more 2144 // descriptive. 2145 // 2146 // TODO(andyk): It'd be nice to have this return SqlString() method output, 2147 // since that is more descriptive. 2148 func (t *T) String() string { 2149 switch t.Family() { 2150 case CollatedStringFamily: 2151 if t.Locale() == "" { 2152 // Used in telemetry. 2153 return fmt.Sprintf("collated%s{*}", t.Name()) 2154 } 2155 return fmt.Sprintf("collated%s{%s}", t.Name(), t.Locale()) 2156 2157 case ArrayFamily: 2158 switch t.Oid() { 2159 case oid.T_oidvector, oid.T_int2vector: 2160 return t.Name() 2161 } 2162 return t.ArrayContents().String() + "[]" 2163 2164 case TupleFamily: 2165 var buf bytes.Buffer 2166 buf.WriteString("tuple") 2167 if len(t.TupleContents()) != 0 && !IsWildcardTupleType(t) { 2168 buf.WriteByte('{') 2169 for i, typ := range t.TupleContents() { 2170 if i != 0 { 2171 buf.WriteString(", ") 2172 } 2173 buf.WriteString(typ.String()) 2174 if t.TupleLabels() != nil { 2175 buf.WriteString(" AS ") 2176 buf.WriteString(t.InternalType.TupleLabels[i]) 2177 } 2178 } 2179 buf.WriteByte('}') 2180 } 2181 return buf.String() 2182 case IntervalFamily, TimestampFamily, TimestampTZFamily, TimeFamily, TimeTZFamily: 2183 if t.InternalType.Precision > 0 || t.InternalType.TimePrecisionIsSet { 2184 return fmt.Sprintf("%s(%d)", t.Name(), t.Precision()) 2185 } 2186 } 2187 return t.Name() 2188 } 2189 2190 // DebugString returns a detailed dump of the type protobuf struct, suitable for 2191 // debugging scenarios. 2192 func (t *T) DebugString() string { 2193 if t.Family() == ArrayFamily && t.ArrayContents().UserDefined() { 2194 // In the case that this type is an array that contains a user defined 2195 // type, the introspection that protobuf performs to generate a string 2196 // representation will panic if the UserDefinedTypeMetadata field of the 2197 // type is populated. It seems to not understand that fields in the element 2198 // T could be not generated by proto, and panics trying to operate on the 2199 // TypeMeta field of the T. To get around this, we just deep copy the T and 2200 // zero out the type metadata to placate proto. See the following issue for 2201 // details: https://github.com/gogo/protobuf/issues/693. 2202 internalTypeCopy := protoutil.Clone(&t.InternalType).(*InternalType) 2203 internalTypeCopy.ArrayContents.TypeMeta = UserDefinedTypeMetadata{} 2204 return internalTypeCopy.String() 2205 } 2206 return t.InternalType.String() 2207 } 2208 2209 // IsAmbiguous returns true if this type is in UnknownFamily or AnyFamily. 2210 // Instances of ambiguous types can be NULL or be in one of several different 2211 // type families. This is important for parameterized types to determine whether 2212 // they are fully concrete or not. 2213 func (t *T) IsAmbiguous() bool { 2214 switch t.Family() { 2215 case UnknownFamily, AnyFamily: 2216 return true 2217 case CollatedStringFamily: 2218 return t.Locale() == "" 2219 case TupleFamily: 2220 if len(t.TupleContents()) == 0 { 2221 return true 2222 } 2223 for i := range t.TupleContents() { 2224 if t.TupleContents()[i].IsAmbiguous() { 2225 return true 2226 } 2227 } 2228 return false 2229 case ArrayFamily: 2230 return t.ArrayContents().IsAmbiguous() 2231 case EnumFamily: 2232 return t.Oid() == oid.T_anyenum 2233 } 2234 return false 2235 } 2236 2237 // EnumGetIdxOfPhysical returns the index within the TypeMeta's slice of 2238 // enum physical representations that matches the input byte slice. 2239 func (t *T) EnumGetIdxOfPhysical(phys []byte) (int, error) { 2240 t.ensureHydratedEnum() 2241 // TODO (rohany): We can either use a map or just binary search here 2242 // since the physical representations are sorted. 2243 reps := t.TypeMeta.EnumData.PhysicalRepresentations 2244 for i := range reps { 2245 if bytes.Equal(phys, reps[i]) { 2246 return i, nil 2247 } 2248 } 2249 err := errors.Newf( 2250 "could not find %v in enum representation %s", 2251 phys, 2252 t.TypeMeta.EnumData.debugString(), 2253 ) 2254 return 0, err 2255 } 2256 2257 // EnumGetIdxOfLogical returns the index within the TypeMeta's slice of 2258 // enum logical representations that matches the input string. 2259 func (t *T) EnumGetIdxOfLogical(logical string) (int, error) { 2260 t.ensureHydratedEnum() 2261 reps := t.TypeMeta.EnumData.LogicalRepresentations 2262 for i := range reps { 2263 if reps[i] == logical { 2264 return i, nil 2265 } 2266 } 2267 return 0, pgerror.Newf( 2268 pgcode.InvalidTextRepresentation, "invalid input value for enum %s: %q", t, logical) 2269 } 2270 2271 func (t *T) ensureHydratedEnum() { 2272 if t.TypeMeta.EnumData == nil { 2273 panic(errors.AssertionFailedf("use of enum metadata before hydration as an enum")) 2274 } 2275 } 2276 2277 // IsStringType returns true iff the given type is String or a collated string 2278 // type. 2279 func IsStringType(t *T) bool { 2280 switch t.Family() { 2281 case StringFamily, CollatedStringFamily: 2282 return true 2283 default: 2284 return false 2285 } 2286 } 2287 2288 // IsValidArrayElementType returns true if the given type can be used as the 2289 // element type of an ArrayFamily-typed column. If the valid return is false, 2290 // the issue number should be included in the error report to inform the user. 2291 func IsValidArrayElementType(t *T) (valid bool, issueNum int) { 2292 switch t.Family() { 2293 case JsonFamily: 2294 return false, 23468 2295 default: 2296 return true, 0 2297 } 2298 } 2299 2300 // CheckArrayElementType ensures that the given type can be used as the element 2301 // type of an ArrayFamily-typed column. If not, it returns an error. 2302 func CheckArrayElementType(t *T) error { 2303 if ok, issueNum := IsValidArrayElementType(t); !ok { 2304 return unimplemented.NewWithIssueDetailf(issueNum, t.String(), 2305 "arrays of %s not allowed", t) 2306 } 2307 return nil 2308 } 2309 2310 // IsDateTimeType returns true if the given type is a date or time-related type. 2311 func IsDateTimeType(t *T) bool { 2312 switch t.Family() { 2313 case DateFamily: 2314 return true 2315 case TimeFamily: 2316 return true 2317 case TimeTZFamily: 2318 return true 2319 case TimestampFamily: 2320 return true 2321 case TimestampTZFamily: 2322 return true 2323 case IntervalFamily: 2324 return true 2325 default: 2326 return false 2327 } 2328 } 2329 2330 // IsAdditiveType returns true if the given type supports addition and 2331 // subtraction. 2332 func IsAdditiveType(t *T) bool { 2333 switch t.Family() { 2334 case IntFamily: 2335 return true 2336 case FloatFamily: 2337 return true 2338 case DecimalFamily: 2339 return true 2340 default: 2341 return IsDateTimeType(t) 2342 } 2343 } 2344 2345 // IsWildcardTupleType returns true if this is the wildcard AnyTuple type. The 2346 // wildcard type matches a tuple type having any number of fields (including 0). 2347 func IsWildcardTupleType(t *T) bool { 2348 return len(t.TupleContents()) == 1 && t.TupleContents()[0].Family() == AnyFamily 2349 } 2350 2351 // collatedStringTypeSQL returns the string representation of a COLLATEDSTRING 2352 // or []COLLATEDSTRING type. This is tricky in the case of an array of collated 2353 // string, since brackets must precede the COLLATE identifier: 2354 // 2355 // STRING COLLATE EN 2356 // VARCHAR(20)[] COLLATE DE 2357 // 2358 func (t *T) collatedStringTypeSQL(isArray bool) string { 2359 var buf bytes.Buffer 2360 buf.WriteString(t.stringTypeSQL()) 2361 if isArray { 2362 buf.WriteString("[] COLLATE ") 2363 } else { 2364 buf.WriteString(" COLLATE ") 2365 } 2366 lex.EncodeLocaleName(&buf, t.Locale()) 2367 return buf.String() 2368 } 2369 2370 // stringTypeSQL returns the visible type name plus any width specifier for the 2371 // STRING/COLLATEDSTRING type. 2372 func (t *T) stringTypeSQL() string { 2373 typName := "STRING" 2374 switch t.Oid() { 2375 case oid.T_varchar: 2376 typName = "VARCHAR" 2377 case oid.T_bpchar: 2378 typName = "CHAR" 2379 case oid.T_char: 2380 // Yes, that's the name. The ways of PostgreSQL are inscrutable. 2381 typName = `"char"` 2382 case oid.T_name: 2383 typName = "NAME" 2384 } 2385 2386 // In general, if there is a specified width we want to print it next to the 2387 // type. However, in the specific case of CHAR and "char", the default is 1 2388 // and the width should be omitted in that case. 2389 if t.Width() > 0 { 2390 o := t.Oid() 2391 if t.Width() != 1 || (o != oid.T_bpchar && o != oid.T_char) { 2392 typName = fmt.Sprintf("%s(%d)", typName, t.Width()) 2393 } 2394 } 2395 2396 return typName 2397 } 2398 2399 // StableTypeIDToOID converts a stable descriptor ID into a type OID. 2400 func StableTypeIDToOID(id uint32) oid.Oid { 2401 return oid.Oid(id) + oidext.CockroachPredefinedOIDMax 2402 } 2403 2404 // UserDefinedTypeOIDToID converts a user defined type OID into a stable 2405 // descriptor ID. 2406 func UserDefinedTypeOIDToID(oid oid.Oid) uint32 { 2407 return uint32(oid) - oidext.CockroachPredefinedOIDMax 2408 } 2409 2410 // Silence unused warnings. 2411 var _ = UserDefinedTypeOIDToID 2412 2413 var typNameLiterals map[string]*T 2414 2415 func init() { 2416 typNameLiterals = make(map[string]*T) 2417 for o, t := range OidToType { 2418 name, ok := oidext.TypeName(o) 2419 if !ok { 2420 panic(errors.AssertionFailedf("oid %d has no type name", o)) 2421 } 2422 name = strings.ToLower(name) 2423 if _, ok := typNameLiterals[name]; !ok { 2424 typNameLiterals[name] = t 2425 } 2426 } 2427 for name, t := range unreservedTypeTokens { 2428 if _, ok := typNameLiterals[name]; !ok { 2429 typNameLiterals[name] = t 2430 } 2431 } 2432 } 2433 2434 // TypeForNonKeywordTypeName returns the column type for the string name of a 2435 // type, if one exists. The third return value indicates: 2436 // 2437 // 0 if no error or the type is not known in postgres. 2438 // -1 if the type is known in postgres. 2439 // >0 for a github issue number. 2440 func TypeForNonKeywordTypeName(name string) (*T, bool, int) { 2441 t, ok := typNameLiterals[name] 2442 if ok { 2443 return t, ok, 0 2444 } 2445 return nil, false, postgresPredefinedTypeIssues[name] 2446 } 2447 2448 // The SERIAL types are pseudo-types that are only used during parsing. After 2449 // that, they should behave identically to INT columns. They are declared 2450 // as INT types, but using different instances than types.Int, types.Int2, etc. 2451 // so that they can be compared by pointer to differentiate them from the 2452 // singleton INT types. While the usual requirement is that == is never used to 2453 // compare types, this is one case where it's allowed. 2454 var ( 2455 Serial2Type = *Int2 2456 Serial4Type = *Int4 2457 Serial8Type = *Int 2458 ) 2459 2460 // IsSerialType returns whether or not the input type is a SERIAL type. 2461 // This function should only be used during parsing. 2462 func IsSerialType(typ *T) bool { 2463 // This is a special case where == is used to compare types, since the SERIAL 2464 // types are pseudo-types. 2465 return typ == &Serial2Type || typ == &Serial4Type || typ == &Serial8Type 2466 } 2467 2468 // unreservedTypeTokens contain type alias that we resolve during parsing. 2469 // Instead of adding a new token to the parser, add the type here. 2470 var unreservedTypeTokens = map[string]*T{ 2471 "blob": Bytes, 2472 "bool": Bool, 2473 "bytea": Bytes, 2474 "bytes": Bytes, 2475 "date": Date, 2476 "float4": Float, 2477 "float8": Float, 2478 "inet": INet, 2479 "int2": Int2, 2480 "int4": Int4, 2481 "int8": Int, 2482 "int64": Int, 2483 "int2vector": Int2Vector, 2484 "json": Jsonb, 2485 "jsonb": Jsonb, 2486 "name": Name, 2487 "oid": Oid, 2488 "oidvector": OidVector, 2489 // Postgres OID pseudo-types. See https://www.postgresql.org/docs/9.4/static/datatype-oid.html. 2490 "regclass": RegClass, 2491 "regproc": RegProc, 2492 "regprocedure": RegProcedure, 2493 "regnamespace": RegNamespace, 2494 "regtype": RegType, 2495 2496 "serial2": &Serial2Type, 2497 "serial4": &Serial4Type, 2498 "serial8": &Serial8Type, 2499 "smallserial": &Serial2Type, 2500 "bigserial": &Serial8Type, 2501 2502 "string": String, 2503 "uuid": Uuid, 2504 } 2505 2506 // The following map must include all types predefined in PostgreSQL 2507 // that are also not yet defined in CockroachDB and link them to 2508 // github issues. It is also possible, but not necessary, to include 2509 // PostgreSQL types that are already implemented in CockroachDB. 2510 var postgresPredefinedTypeIssues = map[string]int{ 2511 "box": 21286, 2512 "cidr": 18846, 2513 "circle": 21286, 2514 "line": 21286, 2515 "lseg": 21286, 2516 "macaddr": -1, 2517 "macaddr8": -1, 2518 "money": -1, 2519 "path": 21286, 2520 "pg_lsn": -1, 2521 "tsquery": 7821, 2522 "tsvector": 7821, 2523 "txid_snapshot": -1, 2524 "xml": -1, 2525 } 2526 2527 // SQLString outputs the GeoMetadata in a SQL-compatible string. 2528 func (m *GeoMetadata) SQLString() string { 2529 // If SRID is available, display both shape and SRID. 2530 // If shape is available but not SRID, just display shape. 2531 if m.SRID != 0 { 2532 shapeName := strings.ToLower(m.Shape.String()) 2533 if m.Shape == geopb.Shape_Unset { 2534 shapeName = "geometry" 2535 } 2536 return fmt.Sprintf("(%s,%d)", shapeName, m.SRID) 2537 } else if m.Shape != geopb.Shape_Unset { 2538 return fmt.Sprintf("(%s)", m.Shape) 2539 } 2540 return "" 2541 }