A menudo veo gente hablando "char"
. Nunca lo he usado. Se define en los documentos como,
El tipo "char" (tenga en cuenta las comillas) es diferente de char (1) en que solo usa un byte de almacenamiento. Se utiliza internamente en los catálogos del sistema como un tipo de enumeración simplista.
Y además,
"char" 1 byte single-byte internal type
Entonces, si es un byte, ¿cuál es el dominio y cómo lo utilizarías? ¿Está firmado o sin firmar? En esta publicación de @Erwin Brandstetter lo expone , pero todavía estoy confundido. Él está usando ascii()
y chr()
, y proporciona esto
SELECT i
, chr(i)::"char" AS i_encoded
, ascii(chr(i)::"char") AS i_decoded
FROM generate_series(1,256) i;
Eso está haciendo algo realmente extraño entre 10 y 11.
i | i_encoded | i_decoded
-----+-----------+-----------
...
8 | \x08 | 8
9 | | 9
10 | +| 10
| | -- WTF is going on here.
11 | \x0B | 11
12 | \x0C | 12
...
También se pone realmente extraño aquí:
126 | ~ | 126
127 | \x7F | 127
128 | | 128
129 | | 128
130 | | 128
131 | | 128
¿Por qué se decodifica todo al norte de 128 como 128? Pero para llevar el bizzare un poco, después de 192 hay un interruptor y se decodifican como 192 ..
190 | | 128
191 | | 128
192 | | 192
193 | | 192
194 | | 192
195 | | 192
196 | | 192
197 | | 192
Erwin dice
Hay varios caracteres que no se deben mostrar. Así que codifique antes de almacenar y decodifique antes de mostrar ...
Sin embargo, no estoy seguro de por qué deberíamos codificar si estamos haciendo exactamente lo que esa pregunta plantea
CREATE TABLE foo AS
SELECT i::"char"
FROM generate_series(-128,127) i;
Eso funciona bien Podemos recuperar las entradas usando
SELECT i::int FROM foo;
En resumen,
- ¿Qué está haciendo el código de Erwin entre el 10 y el 11 cuando el i se anula?
- ¿Por qué se repiten 128 tantas veces?
- ¿Por qué se repite 192 tantas veces?
¿Cómo puedo activar la imposibilidad de almacenar 0, cuando Erwin dice que no puede codificar 0 de esta manera (no se permite el carácter nulo)
CREATE TABLE foo AS SELECT 0::int::"char" AS x; SELECT x::int FROM foo; x --- 0
fuente
psql
es un error o algo extraño. Se termina de la línea, y luego se salta una línea?Para hacer el cambio al rango firmado, puede crear algunas funciones para ayudar a ayudar. Esta lista creará funciones que no se convertirán para ayudar en este proceso de pasar de un rango int de
[0-255]
un byte sin signo a un rango de un byte con signo que requiere el carácter[-128,127]
.pguint
proporciona un tipouint1
que proporciona almacenamiento como un int de un byte sin signo. Si eres capaz de compilar e instalar extensiones, debes considerar eso.pg_uchar
. Puede encontrar elinstall.sql
archivo en ese repositorio.Ejemplo
Un extracto de README
Ahora puede hacer, por ejemplo, almacenar los valores en el rango de
[0-255]
en la tabla.Conviértalos a
bit(8)
Tal vez desee borrar los dos bits de orden inferior, puede hacerlo con BITWISE-AND,
fuente