Разговор о DOMAINS интересен, но не имеет отношения к единственно возможному источнику этого вопроса. Желание беззнаковых целых чисел состоит в том, чтобы удвоить диапазон целых чисел с тем же количеством битов, это аргумент эффективности, а не желание исключить отрицательные числа, каждый знает, как добавить ограничение проверки.
Когда кто-то спросил об этом , Том Лейн сказал:
По сути, это нулевой шанс, что это произойдет, если вы не найдете способ вписать их в числовую иерархию продвижения, которая не нарушила бы многие существующие приложения. Мы смотрели на это не раз, если мне не изменяет память, и не смогли придумать работоспособный дизайн, который, похоже, не нарушал бы POLA.
Что такое «ПОЛА»? Google дал мне 10 результатов, которые не имеют смысла . Не уверен, что это политически некорректная мысль и поэтому подвергается цензуре. Почему этот поисковый запрос не даст никакого результата? Без разницы.
Вы можете без особых проблем реализовать беззнаковые целые числа как типы расширения. Если вы сделаете это с помощью C-функций, то вообще не будет никаких штрафов за производительность. Вам не нужно расширять синтаксический анализатор для работы с литералами, потому что PgSQL имеет такой простой способ интерпретировать строки как литералы, просто напишите '4294966272' :: uint4 в качестве литералов. Броски тоже не должны иметь большого значения. Вам даже не нужно делать исключения диапазона, вы можете просто обработать семантику '4294966273' :: uint4 :: int как -1024. Или можете выдать ошибку.
Если бы я этого хотел, я бы это сделал. Но поскольку я использую Java на другой стороне SQL, для меня это не имеет большого значения, поскольку в Java нет этих целых чисел без знака. Так что я ничего не получаю. Меня уже раздражает, если я получаю BigInteger из столбца bigint, когда он должен уместиться в long.
Другое дело, если бы мне действительно нужно было хранить 32-битные или 64-битные типы, я мог бы использовать PostgreSQL int4 или int8 соответственно, просто помня, что естественный порядок или арифметика не будут работать надежно. Но на хранение и извлечение это не влияет.
Вот как я могу реализовать простой беззнаковый int8:
Сначала я буду использовать
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
)
минимальные 2 функции, uint8_in
и uint8_out
я должен сначала определить.
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;
необходимо реализовать это в C uint8_funcs.c. Итак, я использую сложный пример отсюда и упрощаю его:
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);
}
ну ладно, или ты можешь просто найти это уже готовым .