A conversa sobre DOMAINS é interessante, mas não relevante para a única origem possível dessa questão. O desejo de ints sem sinal é dobrar o intervalo de ints com o mesmo número de bits, é um argumento de eficiência, não o desejo de excluir números negativos, todo mundo sabe como adicionar uma restrição de verificação.
Quando questionado por alguém sobre isso , Tome Lane afirmou:
Basicamente, a chance de isso acontecer é zero, a menos que você encontre uma maneira de encaixá-los na hierarquia de promoção numérica que não interrompa muitos dos aplicativos existentes. Já vimos isso mais de uma vez, se não me falha a memória, e não conseguimos encontrar um design viável que não parecesse violar o POLA.
O que é "POLA"? O Google me deu 10 resultados sem sentido . Não tenho certeza se é pensamento politicamente incorreto e, portanto, censurado. Por que este termo de pesquisa não produziria nenhum resultado? Tanto faz.
Você pode implementar ints não assinados como tipos de extensão sem muitos problemas. Se você fizer isso com funções C, não haverá nenhuma penalidade de desempenho. Você não precisará estender o analisador para lidar com literais porque o PgSQL tem uma maneira fácil de interpretar strings como literais, basta escrever '4294966272' :: uint4 como seus literais. Casts também não deveriam ser um grande negócio. Você nem mesmo precisa fazer exceções de intervalo, você pode apenas tratar a semântica de '4294966273' :: uint4 :: int como -1024. Ou você pode lançar um erro.
Se eu quisesse, eu teria feito. Mas como estou usando Java no outro lado do SQL, para mim tem pouco valor, já que o Java também não tem esses inteiros sem sinal. Portanto, não ganho nada. Já fico chateado se obtiver um BigInteger de uma coluna bigint, quando deveria caber em longa.
Outra coisa, se eu tivesse a necessidade de armazenar tipos de 32 ou 64 bits, posso usar PostgreSQL int4 ou int8 respectivamente, apenas lembrando que a ordem natural ou aritmética não funcionará de forma confiável. Mas o armazenamento e a recuperação não são afetados por isso.
Aqui está como posso implementar um int8 simples sem sinal:
Primeiro vou usar
CREATE TYPE name (
INPUT = uint8_in,
OUTPUT = uint8_out
[, RECEIVE = uint8_receive ]
[, SEND = uint8_send ]
[, ANALYZE = uint8_analyze ]
, INTERNALLENGTH = 8
, PASSEDBYVALUE ]
, ALIGNMENT = 8
, STORAGE = plain
, CATEGORY = N
, PREFERRED = false
, DEFAULT = null
)
as 2 funções mínimas uint8_in
e uint8_out
devo primeiro definir.
CREATE FUNCTION uint8_in(cstring)
RETURNS uint8
AS 'uint8_funcs'
LANGUAGE C IMMUTABLE STRICT;
CREATE FUNCTION uint64_out(complex)
RETURNS cstring
AS 'uint8_funcs'
LANGUAGE C IMMUTABLE STRICT;
precisa implementar isso em C uint8_funcs.c. Então, vou usar o exemplo complexo a partir daqui e torná-lo simples:
PG_FUNCTION_INFO_V1(complex_in);
Datum complex_in(PG_FUNCTION_ARGS) {
char *str = PG_GETARG_CSTRING(0);
uint64_t result;
if(sscanf(str, "%llx" , &result) != 1)
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
errmsg("invalid input syntax for uint8: \"%s\"", str)));
return (Datum)SET_8_BYTES(result);
}
bem, ou você pode simplesmente descobrir que está pronto .