void LoadBackendType(DbDataReader reader, NpgsqlConnector connector)
        {
            var ns   = reader.GetString(reader.GetOrdinal("nspname"));
            var name = reader.GetString(reader.GetOrdinal("typname"));
            var oid  = Convert.ToUInt32(reader[reader.GetOrdinal("oid")]);

            Debug.Assert(name != null);
            Debug.Assert(oid != 0);

            var typeChar = reader.GetString(reader.GetOrdinal("type"))[0];

            switch (typeChar)
            {
            case 'b':  // Normal base type
                var baseType = new PostgresBaseType(ns, name, oid);
                Add(baseType);
                BaseTypes.Add(baseType);
                return;

            case 'a': // Array
            {
                var elementOID = Convert.ToUInt32(reader[reader.GetOrdinal("elemoid")]);
                Debug.Assert(elementOID > 0);
                if (!ByOID.TryGetValue(elementOID, out var elementPostgresType))
                {
                    Log.Trace($"Array type '{name}' refers to unknown element with OID {elementOID}, skipping", connector.Id);
                    return;
                }

                var arrayType = new PostgresArrayType(ns, name, oid, elementPostgresType);
                Add(arrayType);
                ArrayTypes.Add(arrayType);
                return;
            }

            case 'r': // Range
            {
                var elementOID = Convert.ToUInt32(reader[reader.GetOrdinal("elemoid")]);
                Debug.Assert(elementOID > 0);
                if (!ByOID.TryGetValue(elementOID, out var subtypePostgresType))
                {
                    Log.Trace($"Range type '{name}' refers to unknown subtype with OID {elementOID}, skipping", connector.Id);
                    return;
                }

                var rangeType = new PostgresRangeType(ns, name, oid, subtypePostgresType);
                Add(rangeType);
                RangeTypes.Add(rangeType);
                return;
            }

            case 'e':   // Enum
                var enumType = new PostgresEnumType(ns, name, oid);
                Add(enumType);
                EnumTypes.Add(enumType);
                return;

            case 'c':   // Composite
                var compositeType = new PostgresCompositeType(ns, name, oid);
                Add(compositeType);
                CompositeTypes.Add(compositeType);
                return;

            case 'd':   // Domain
                var baseTypeOID = Convert.ToUInt32(reader[reader.GetOrdinal("typbasetype")]);
                Debug.Assert(baseTypeOID > 0);
                if (!ByOID.TryGetValue(baseTypeOID, out var basePostgresType))
                {
                    Log.Trace($"Domain type '{name}' refers to unknown base type with OID {baseTypeOID}, skipping", connector.Id);
                    return;
                }
                var domainType = new PostgresDomainType(ns, name, oid, basePostgresType);
                Add(domainType);
                DomainTypes.Add(domainType);
                return;

            case 'p':   // pseudo-type (record, void)
                // Hack this as a base type
                goto case 'b';

            default:
                throw new ArgumentOutOfRangeException($"Unknown typtype for type '{name}' in pg_type: {typeChar}");
            }
        }