Costumo ver pessoas falando "char"
. Eu nunca usei isso. É definido nos documentos como,
O tipo "char" (observe as aspas) é diferente de char (1), pois ele usa apenas um byte de armazenamento. É usado internamente nos catálogos do sistema como um tipo de enumeração simplista.
E além disso,
"char" 1 byte single-byte internal type
Então, se é um byte, qual é o domínio e como você o utilizaria? É assinado ou não assinado? Neste post de @Erwin Brandstetter, ele explica tudo , mas ainda estou confuso. Ele está usando ascii()
e chr()
, e fornece isso
SELECT i
, chr(i)::"char" AS i_encoded
, ascii(chr(i)::"char") AS i_decoded
FROM generate_series(1,256) i;
Isso está fazendo algo realmente estranho entre 10 e 11.
i | i_encoded | i_decoded
-----+-----------+-----------
...
8 | \x08 | 8
9 | | 9
10 | +| 10
| | -- WTF is going on here.
11 | \x0B | 11
12 | \x0C | 12
...
Também fica muito estranho aqui:
126 | ~ | 126
127 | \x7F | 127
128 | | 128
129 | | 128
130 | | 128
131 | | 128
Por que tudo ao norte de 128 está sendo decodificado como 128? Mas, para aguentar um pouco, depois de 192, há um interruptor e eles são decodificados como 192 ..
190 | | 128
191 | | 128
192 | | 192
193 | | 192
194 | | 192
195 | | 192
196 | | 192
197 | | 192
Erwin diz
Existem vários caracteres não destinados à exibição. Portanto, codifique antes de armazenar e decodifique antes de exibir ...
Não sei ao certo por que devemos codificar, se estamos fazendo exatamente o que essas perguntas fazem.
CREATE TABLE foo AS
SELECT i::"char"
FROM generate_series(-128,127) i;
Isso funciona bem. Podemos recuperar as entradas usando
SELECT i::int FROM foo;
Então, resumindo,
- O que o código de Erwin está fazendo entre 10 e 11, onde o i é nulo?
- Por que 128 é repetido tantas vezes?
- Por que 192 é repetido tantas vezes?
Como acionar a incapacidade de armazenar 0, quando Erwin diz que você não pode codificar 0 dessa maneira (caractere nulo não permitido)
CREATE TABLE foo AS SELECT 0::int::"char" AS x; SELECT x::int FROM foo; x --- 0
fonte
psql
é um bug ou algo estranho. Ele termina a linha e depois pula uma linha?Para mudar para o intervalo assinado, você pode criar algumas funções para ajudar na assistência. Esta lista criará funções que não são convertidas para ajudar no processo de passar de um intervalo int não assinado de um byte
[0-255]
para um intervalo assinado de um byte que o caractere exige[-128,127]
.pguint
fornece um tipouint1
que fornece armazenamento como um int não assinado de um byte. Se você é capaz de compilar e instalar extensões, considere isso.pg_uchar
. Você pode encontrar oinstall.sql
arquivo nesse repositório.Exemplo
Um extrato do README
Agora você pode, por exemplo, armazenar os valores no intervalo da
[0-255]
tabela.Converta-os em
bit(8)
Talvez você queira limpar os dois bits de ordem inferior, você pode fazer isso com BITWISE-AND,
fonte