Rozmowa o DOMENACH jest interesująca, ale nie dotyczy jedynego możliwego źródła tego pytania. Dążenie do liczby int bez znaku polega na podwojeniu zakresu liczb całkowitych przy tej samej liczbie bitów, jest to argument wydajności, a nie chęć wykluczenia liczb ujemnych, każdy wie, jak dodać ograniczenie sprawdzające.
Kiedy zapytany przez kogoś o tym , Tome Lane stwierdził:
Zasadniczo istnieje zerowa szansa, że tak się stanie, jeśli nie znajdziesz sposobu na dopasowanie ich do numerycznej hierarchii promocji, który nie zepsuje wielu istniejących aplikacji. Patrzyliśmy na to więcej niż raz, jeśli pamięć służy, i nie udało nam się stworzyć działającego projektu, który nie wydawałby się naruszać POLA.
Co to jest „POLA”? Google dał mi 10 wyników, które są bez znaczenia . Nie jestem pewien, czy jest to myśl politycznie niepoprawna, a zatem ocenzurowana. Dlaczego to wyszukiwane hasło nie daje żadnych wyników? Cokolwiek.
Możesz implementować niepodpisane liczby int jako typy rozszerzeń bez większych problemów. Jeśli zrobisz to za pomocą funkcji C, nie będzie żadnych kar za wydajność. Nie musisz rozszerzać parsera, aby zajmował się literałami, ponieważ PgSQL ma tak łatwy sposób interpretowania łańcuchów jako literałów, po prostu wpisz '4294966272' :: uint4 jako swoje literały. Rzuty też nie powinny być wielkim problemem. Nie musisz nawet robić wyjątków zakresów, możesz po prostu traktować semantykę '4294966273' :: uint4 :: int jako -1024. Lub możesz zgłosić błąd.
Gdybym tego chciał, zrobiłbym to. Ale ponieważ używam Javy po drugiej stronie SQL, ma to dla mnie niewielką wartość, ponieważ Java również nie ma tych liczb całkowitych bez znaku. Więc nic nie zyskuję. Jestem już zirytowany, gdy dostaję BigInteger z kolumny biginta, kiedy powinien pasować do long.
Inna sprawa, gdybym miał potrzebę przechowywania typów 32-bitowych lub 64-bitowych, mogę użyć odpowiednio PostgreSQL int4 lub int8, pamiętając tylko, że naturalna kolejność lub arytmetyka nie będą działać niezawodnie. Nie ma to jednak wpływu na przechowywanie i odzyskiwanie.
Oto jak mogę zaimplementować proste bez znaku int8:
Najpierw użyję
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
)
minimum 2 funkcje uint8_in
i uint8_out
muszę najpierw zdefiniować.
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;
trzeba to zaimplementować w C uint8_funcs.c. Więc skorzystam ze złożonego przykładu z tego miejsca i uproszczę to:
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);
}
no cóż, albo możesz po prostu znaleźć to już zrobione .