Il discorso sui DOMINI è interessante ma non pertinente all'unica possibile origine di quella domanda. Il desiderio di int senza segno è di raddoppiare l'intervallo di int con lo stesso numero di bit, è un argomento di efficienza, non il desiderio di escludere numeri negativi, tutti sanno come aggiungere un vincolo di controllo.
Alla domanda di qualcuno al riguardo , Tome Lane ha dichiarato:
Fondamentalmente, non ci sono possibilità che ciò accada a meno che non si riesca a trovare un modo per inserirli nella gerarchia delle promozioni numeriche che non interrompa molte applicazioni esistenti. Abbiamo esaminato questo aspetto più di una volta, se la memoria serve, e non siamo riusciti a trovare un design funzionante che non sembrava violare il POLA.
Cos'è la "POLA"? Google mi ha dato 10 risultati privi di significato . Non sono sicuro che sia un pensiero politicamente scorretto e quindi censurato. Perché questo termine di ricerca non produce alcun risultato? Qualunque cosa.
Puoi implementare int senza segno come tipi di estensione senza troppi problemi. Se lo fai con le funzioni C, non ci saranno affatto penalità sulle prestazioni. Non sarà necessario estendere il parser per gestire i letterali perché PgSQL ha un modo così semplice per interpretare le stringhe come letterali, basta scrivere "4294966272" :: uint4 come letterali. Anche i cast non dovrebbero essere un grosso problema. Non è nemmeno necessario fare eccezioni di intervallo, puoi semplicemente trattare la semantica di "4294966273" :: uint4 :: int come -1024. Oppure puoi lanciare un errore.
Se avessi voluto questo, l'avrei fatto. Ma dal momento che sto usando Java sull'altro lato di SQL, per me è di scarso valore poiché Java non ha nemmeno quegli interi senza segno. Quindi non guadagno nulla. Sono già infastidito se ottengo un BigInteger da una colonna bigint, quando dovrebbe rientrare in long.
Un'altra cosa, se avessi la necessità di memorizzare i tipi a 32 o 64 bit, posso usare PostgreSQL int4 o int8 rispettivamente, ricordando solo che l'ordine naturale o l'aritmetica non funzioneranno in modo affidabile. Ma la memorizzazione e il recupero non ne sono influenzati.
Ecco come posso implementare un semplice int8 senza segno:
Per prima cosa userò
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
)
le 2 funzioni minime uint8_in
e uint8_out
devo prima definire.
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;
è necessario implementarlo in C uint8_funcs.c. Quindi uso l'esempio complesso da qui e lo rendo semplice:
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 beh, o puoi semplicemente trovarlo già fatto .