github.com/cockroachdb/cockroachdb-parser@v0.23.3-0.20240213214944-911057d40c9a/pkg/sql/types/oid.go (about)

     1  // Copyright 2017 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  	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/oidext"
    15  	"github.com/cockroachdb/errors"
    16  	"github.com/lib/pq/oid"
    17  )
    18  
    19  // Convenience list of pre-constructed OID-related types.
    20  var (
    21  	// Oid is the type of a Postgres Object ID value.
    22  	Oid = &T{InternalType: InternalType{
    23  		Family: OidFamily, Oid: oid.T_oid, Locale: &emptyLocale}}
    24  
    25  	// Regclass is the type of a Postgres regclass OID variant (T_regclass).
    26  	RegClass = &T{InternalType: InternalType{
    27  		Family: OidFamily, Oid: oid.T_regclass, Locale: &emptyLocale}}
    28  
    29  	// RegNamespace is the type of a Postgres regnamespace OID variant
    30  	// (T_regnamespace).
    31  	RegNamespace = &T{InternalType: InternalType{
    32  		Family: OidFamily, Oid: oid.T_regnamespace, Locale: &emptyLocale}}
    33  
    34  	// RegProc is the type of a Postgres regproc OID variant (T_regproc).
    35  	RegProc = &T{InternalType: InternalType{
    36  		Family: OidFamily, Oid: oid.T_regproc, Locale: &emptyLocale}}
    37  
    38  	// RegProcedure is the type of a Postgres regprocedure OID variant
    39  	// (T_regprocedure).
    40  	RegProcedure = &T{InternalType: InternalType{
    41  		Family: OidFamily, Oid: oid.T_regprocedure, Locale: &emptyLocale}}
    42  
    43  	// RegRole is the type of a Postgres regrole OID variant (T_regrole).
    44  	RegRole = &T{InternalType: InternalType{
    45  		Family: OidFamily, Oid: oid.T_regrole, Locale: &emptyLocale}}
    46  
    47  	// RegType is the type of of a Postgres regtype OID variant (T_regtype).
    48  	RegType = &T{InternalType: InternalType{
    49  		Family: OidFamily, Oid: oid.T_regtype, Locale: &emptyLocale}}
    50  
    51  	// OidVector is a type-alias for an array of Oid values, but with a different
    52  	// OID (T_oidvector instead of T__oid). It is a special VECTOR type used by
    53  	// Postgres in system tables. OidVectors are 0-indexed, unlike normal arrays.
    54  	OidVector = &T{InternalType: InternalType{
    55  		Family: ArrayFamily, Oid: oid.T_oidvector, ArrayContents: Oid, Locale: &emptyLocale}}
    56  )
    57  
    58  // OidToType maps Postgres object IDs to CockroachDB types.  We export the map
    59  // instead of a method so that other packages can iterate over the map directly.
    60  // Note that additional elements for the array Oid types are added in init().
    61  var OidToType = map[oid.Oid]*T{
    62  	oid.T_anyelement: Any,
    63  	oid.T_bit:        typeBit,
    64  	oid.T_bool:       Bool,
    65  	oid.T_bpchar:     typeBpChar,
    66  	oid.T_bytea:      Bytes,
    67  	oid.T_char:       QChar,
    68  	oid.T_date:       Date,
    69  	oid.T_float4:     Float4,
    70  	oid.T_float8:     Float,
    71  	oid.T_int2:       Int2,
    72  	oid.T_int2vector: Int2Vector,
    73  	oid.T_int4:       Int4,
    74  	oid.T_int8:       Int,
    75  	oid.T_inet:       INet,
    76  	oid.T_interval:   Interval,
    77  	// NOTE(sql-exp): Uncomment the line below if we support the JSON type.
    78  	// This would potentially require us to convert the type descriptors of
    79  	// existing tables.
    80  	// oid.T_json:      Json,
    81  	oid.T_jsonb:        Jsonb,
    82  	oid.T_name:         Name,
    83  	oid.T_numeric:      Decimal,
    84  	oid.T_oid:          Oid,
    85  	oid.T_oidvector:    OidVector,
    86  	oid.T_pg_lsn:       PGLSN,
    87  	oid.T_record:       AnyTuple,
    88  	oid.T_refcursor:    RefCursor,
    89  	oid.T_regclass:     RegClass,
    90  	oid.T_regnamespace: RegNamespace,
    91  	oid.T_regproc:      RegProc,
    92  	oid.T_regprocedure: RegProcedure,
    93  	oid.T_regrole:      RegRole,
    94  	oid.T_regtype:      RegType,
    95  	oid.T_text:         String,
    96  	oid.T_time:         Time,
    97  	oid.T_timetz:       TimeTZ,
    98  	oid.T_timestamp:    Timestamp,
    99  	oid.T_timestamptz:  TimestampTZ,
   100  	oid.T_tsquery:      TSQuery,
   101  	oid.T_tsvector:     TSVector,
   102  	oid.T_unknown:      Unknown,
   103  	oid.T_uuid:         Uuid,
   104  	oid.T_varbit:       VarBit,
   105  	oid.T_varchar:      VarChar,
   106  	oid.T_void:         Void,
   107  
   108  	oidext.T_geometry:  Geometry,
   109  	oidext.T_geography: Geography,
   110  	oidext.T_box2d:     Box2D,
   111  }
   112  
   113  // oidToArrayOid maps scalar type Oids to their corresponding array type Oid.
   114  var oidToArrayOid = map[oid.Oid]oid.Oid{
   115  	oid.T_anyelement:   oid.T_anyarray,
   116  	oid.T_bit:          oid.T__bit,
   117  	oid.T_bool:         oid.T__bool,
   118  	oid.T_bpchar:       oid.T__bpchar,
   119  	oid.T_bytea:        oid.T__bytea,
   120  	oid.T_char:         oid.T__char,
   121  	oid.T_date:         oid.T__date,
   122  	oid.T_float4:       oid.T__float4,
   123  	oid.T_float8:       oid.T__float8,
   124  	oid.T_inet:         oid.T__inet,
   125  	oid.T_int2:         oid.T__int2,
   126  	oid.T_int2vector:   oid.T__int2vector,
   127  	oid.T_int4:         oid.T__int4,
   128  	oid.T_int8:         oid.T__int8,
   129  	oid.T_interval:     oid.T__interval,
   130  	oid.T_jsonb:        oid.T__jsonb,
   131  	oid.T_name:         oid.T__name,
   132  	oid.T_numeric:      oid.T__numeric,
   133  	oid.T_oid:          oid.T__oid,
   134  	oid.T_oidvector:    oid.T__oidvector,
   135  	oid.T_pg_lsn:       oid.T__pg_lsn,
   136  	oid.T_record:       oid.T__record,
   137  	oid.T_refcursor:    oid.T__refcursor,
   138  	oid.T_regclass:     oid.T__regclass,
   139  	oid.T_regnamespace: oid.T__regnamespace,
   140  	oid.T_regproc:      oid.T__regproc,
   141  	oid.T_regprocedure: oid.T__regprocedure,
   142  	oid.T_regrole:      oid.T__regrole,
   143  	oid.T_regtype:      oid.T__regtype,
   144  	oid.T_text:         oid.T__text,
   145  	oid.T_time:         oid.T__time,
   146  	oid.T_timetz:       oid.T__timetz,
   147  	oid.T_timestamp:    oid.T__timestamp,
   148  	oid.T_timestamptz:  oid.T__timestamptz,
   149  	oid.T_tsquery:      oid.T__tsquery,
   150  	oid.T_tsvector:     oid.T__tsvector,
   151  	oid.T_uuid:         oid.T__uuid,
   152  	oid.T_varbit:       oid.T__varbit,
   153  	oid.T_varchar:      oid.T__varchar,
   154  
   155  	oidext.T_geometry:  oidext.T__geometry,
   156  	oidext.T_geography: oidext.T__geography,
   157  	oidext.T_box2d:     oidext.T__box2d,
   158  }
   159  
   160  // familyToOid maps each type family to a default OID value that is used when
   161  // another Oid is not present (e.g. when deserializing a type saved by a
   162  // previous version of CRDB).
   163  var familyToOid = map[Family]oid.Oid{
   164  	BoolFamily:           oid.T_bool,
   165  	IntFamily:            oid.T_int8,
   166  	FloatFamily:          oid.T_float8,
   167  	DecimalFamily:        oid.T_numeric,
   168  	DateFamily:           oid.T_date,
   169  	TimestampFamily:      oid.T_timestamp,
   170  	IntervalFamily:       oid.T_interval,
   171  	StringFamily:         oid.T_text,
   172  	BytesFamily:          oid.T_bytea,
   173  	TimestampTZFamily:    oid.T_timestamptz,
   174  	CollatedStringFamily: oid.T_text,
   175  	OidFamily:            oid.T_oid,
   176  	PGLSNFamily:          oid.T_pg_lsn,
   177  	RefCursorFamily:      oid.T_refcursor,
   178  	UnknownFamily:        oid.T_unknown,
   179  	UuidFamily:           oid.T_uuid,
   180  	ArrayFamily:          oid.T_anyarray,
   181  	INetFamily:           oid.T_inet,
   182  	TimeFamily:           oid.T_time,
   183  	TimeTZFamily:         oid.T_timetz,
   184  	JsonFamily:           oid.T_jsonb,
   185  	TSQueryFamily:        oid.T_tsquery,
   186  	TSVectorFamily:       oid.T_tsvector,
   187  	TupleFamily:          oid.T_record,
   188  	BitFamily:            oid.T_bit,
   189  	AnyFamily:            oid.T_anyelement,
   190  
   191  	GeometryFamily:  oidext.T_geometry,
   192  	GeographyFamily: oidext.T_geography,
   193  	Box2DFamily:     oidext.T_box2d,
   194  }
   195  
   196  // ArrayOids is a set of all oids which correspond to an array type.
   197  var ArrayOids = map[oid.Oid]struct{}{}
   198  
   199  func init() {
   200  	for o, ao := range oidToArrayOid {
   201  		ArrayOids[ao] = struct{}{}
   202  		OidToType[ao] = MakeArray(OidToType[o])
   203  	}
   204  }
   205  
   206  // CalcArrayOid returns the OID of the array type having elements of the given
   207  // type.
   208  func CalcArrayOid(elemTyp *T) oid.Oid {
   209  	o := elemTyp.Oid()
   210  	switch elemTyp.Family() {
   211  	case ArrayFamily:
   212  		// Postgres nested arrays return the OID of the nested array (i.e. the
   213  		// OID doesn't change no matter how many levels of nesting there are),
   214  		// except in the special-case of the vector types.
   215  		switch o {
   216  		case oid.T_int2vector, oid.T_oidvector:
   217  			// Vector types have their own array OID types.
   218  		default:
   219  			return o
   220  		}
   221  
   222  	case UnknownFamily:
   223  		// Postgres doesn't have an OID for an array of unknown values, since
   224  		// it's not possible to create that in Postgres. But CRDB does allow that,
   225  		// so return 0 for that case (since there's no T__unknown). This is what
   226  		// previous versions of CRDB returned for this case.
   227  		return unknownArrayOid
   228  
   229  	case EnumFamily:
   230  		return elemTyp.UserDefinedArrayOID()
   231  
   232  	case TupleFamily:
   233  		if elemTyp.UserDefined() {
   234  			if elemTyp.TypeMeta.ImplicitRecordType {
   235  				// We're currently not creating array types for implicitly-defined
   236  				// per-table record types. So, we cheat a little, and return, as the OID
   237  				// for an array of these things, the OID for a generic array of records.
   238  				return oid.T__record
   239  			}
   240  			return elemTyp.UserDefinedArrayOID()
   241  		}
   242  	}
   243  
   244  	// Map the OID of the array element type to the corresponding array OID.
   245  	// This should always be possible for all other OIDs (checked in oid.go
   246  	// init method).
   247  	if o == oid.T_json {
   248  		o = oid.T__json
   249  	} else {
   250  		o = oidToArrayOid[o]
   251  	}
   252  	if o == 0 {
   253  		panic(errors.AssertionFailedf("oid %d couldn't be mapped to array oid", elemTyp.Oid()))
   254  	}
   255  	return o
   256  }