Le discours sur DOMAINES est intéressant mais pas pertinent pour la seule origine possible de cette question. Le désir des entiers non signés est de doubler la plage des entiers avec le même nombre de bits, c'est un argument d'efficacité, pas le désir d'exclure les nombres négatifs, tout le monde sait comment ajouter une contrainte de vérification.
Lorsque demandé par quelqu'un à ce sujet , Tome Lane a déclaré:
Fondamentalement, il n'y a aucune chance que cela se produise à moins que vous ne trouviez un moyen de les intégrer dans la hiérarchie de promotion numérique qui ne casse pas beaucoup d'applications existantes. Nous avons examiné cela plus d'une fois, si ma mémoire est bonne, et n'avons pas réussi à proposer une conception réalisable qui ne semblait pas violer la POLA.
Qu'est-ce que le "POLA"? Google m'a donné 10 résultats qui n'ont aucun sens . Je ne sais pas si c'est une pensée politiquement incorrecte et donc censurée. Pourquoi ce terme de recherche ne donnerait-il aucun résultat? Peu importe.
Vous pouvez implémenter des entiers non signés en tant que types d'extension sans trop de problèmes. Si vous le faites avec des fonctions C, il n'y aura pratiquement aucune pénalité de performance. Vous n'aurez pas besoin d'étendre l'analyseur pour traiter les littéraux car PgSQL a un moyen si simple d'interpréter les chaînes comme des littéraux, écrivez simplement '4294966272' :: uint4 comme vos littéraux. Les moulages ne devraient pas non plus être un problème. Vous n'avez même pas besoin de faire des exceptions de plage, vous pouvez simplement traiter la sémantique de '4294966273' :: uint4 :: int comme -1024. Ou vous pouvez lancer une erreur.
Si je le voulais, je l'aurais fait. Mais comme j'utilise Java de l'autre côté de SQL, pour moi, cela n'a guère de valeur puisque Java n'a pas non plus ces entiers non signés. Alors je ne gagne rien. Je suis déjà ennuyé si j'obtiens un BigInteger d'une colonne bigint, alors qu'il devrait tenir dans long.
Une autre chose, si j'avais besoin de stocker des types 32 bits ou 64 bits, je peux utiliser PostgreSQL int4 ou int8 respectivement, en me souvenant simplement que l'ordre naturel ou l'arithmétique ne fonctionnera pas de manière fiable. Mais le stockage et la récupération ne sont pas affectés par cela.
Voici comment je peux implémenter un simple int8 non signé:
Je vais d'abord utiliser
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
)
les 2 fonctions minimales uint8_in
et uint8_out
je dois d'abord définir.
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;
besoin de l'implémenter dans C uint8_funcs.c. Je vais donc utiliser l'exemple complexe d'ici et le rendre simple:
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);
}
ah bien, ou vous pouvez juste le trouver déjà fait .