La charla sobre DOMINIOS es interesante pero no relevante para el único origen posible de esa pregunta. El deseo de ints sin firmar es duplicar el rango de ints con el mismo número de bits, es un argumento de eficiencia, no el deseo de excluir números negativos, todos saben cómo agregar una restricción de verificación.
Cuando alguien le preguntó al respecto , Tome Lane declaró:
Básicamente, hay cero posibilidades de que esto suceda a menos que pueda encontrar una manera de encajarlos en la jerarquía de promoción numérica que no rompa muchas aplicaciones existentes. Hemos examinado esto más de una vez, si la memoria no me falla, y no pudimos encontrar un diseño viable que no pareciera violar la POLA.
¿Qué es el "POLA"? Google me dio 10 resultados que no tienen sentido . No estoy seguro de si es un pensamiento políticamente incorrecto y, por lo tanto, está censurado. ¿Por qué este término de búsqueda no da ningún resultado? Lo que sea.
Puede implementar entradas sin firmar como tipos de extensión sin demasiados problemas. Si lo hace con funciones C, no habrá ninguna penalización de rendimiento. No necesitará extender el analizador para tratar con literales porque PgSQL tiene una manera tan fácil de interpretar cadenas como literales, simplemente escriba '4294966272' :: uint4 como sus literales. Los yesos tampoco deberían ser un gran problema. Ni siquiera necesita hacer excepciones de rango, simplemente puede tratar la semántica de '4294966273' :: uint4 :: int como -1024. O puede lanzar un error.
Si hubiera querido esto, lo habría hecho. Pero como estoy usando Java en el otro lado de SQL, para mí tiene poco valor ya que Java tampoco tiene esos enteros sin firmar. Entonces no gano nada. Ya estoy molesto si obtengo un BigInteger de una columna bigint, cuando debería caber en long.
Otra cosa, si tuviera la necesidad de almacenar tipos de 32 bits o 64 bits, puedo usar PostgreSQL int4 o int8 respectivamente, solo recordando que el orden natural o la aritmética no funcionarán de manera confiable. Pero el almacenamiento y la recuperación no se ven afectados por eso.
Así es como puedo implementar un int8 simple sin firmar:
Primero usaré
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
)
las 2 funciones mínimas uint8_in
y uint8_out
primero debo definir.
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;
Necesito implementar esto en C uint8_funcs.c. Entonces uso el ejemplo complejo de aquí y lo hago 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, bueno, o puede encontrarlo ya hecho .