Розмова про DOMAINS цікава, але не стосується єдиного можливого походження цього питання. Прагнення до безпідписаних ints полягає в подвоєнні діапазону ints з однаковою кількістю біт, це аргумент ефективності, а не бажання виключати негативні числа, всі знають, як додати обмеження для перевірки.
На запитання когось про це , Том Лейн заявив:
В основному, немає жодного шансу, що це станеться, якщо ви не зможете знайти спосіб їх вписання в числову ієрархію просування, яка не порушує багато існуючих додатків. Ми розглянули це не раз, якщо пам'ять слугує, і не вдалося придумати працездатний дизайн, який, схоже, не порушує 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);
}
ну добре, або ви можете просто знайти це вже зроблено .