Je vois souvent des gens parler "char"
. Je ne l'ai jamais utilisé. Il est défini dans les documents comme,
Le type "char" (notez les guillemets) est différent de char (1) en ce qu'il n'utilise qu'un octet de stockage. Il est utilisé en interne dans les catalogues système en tant que type d'énumération simpliste.
Et plus loin,
"char" 1 byte single-byte internal type
Donc, si c'est un octet, quel est le domaine et comment l'utiliseriez-vous? Est-il signé ou non signé? Dans cet article de @Erwin Brandstetter, il l'expose , mais je suis toujours confus. Il utilise ascii()
et chr()
, et fournit cette
SELECT i
, chr(i)::"char" AS i_encoded
, ascii(chr(i)::"char") AS i_decoded
FROM generate_series(1,256) i;
Cela fait quelque chose de vraiment bizarre entre 10 et 11.
i | i_encoded | i_decoded
-----+-----------+-----------
...
8 | \x08 | 8
9 | | 9
10 | +| 10
| | -- WTF is going on here.
11 | \x0B | 11
12 | \x0C | 12
...
Cela devient aussi vraiment bizarre ici:
126 | ~ | 126
127 | \x7F | 127
128 | | 128
129 | | 128
130 | | 128
131 | | 128
Pourquoi tout au nord de 128 est-il décodé en 128? Mais pour reprendre un peu le bizzare, après 192 il y a un interrupteur et ils sont décodés en 192 ..
190 | | 128
191 | | 128
192 | | 192
193 | | 192
194 | | 192
195 | | 192
196 | | 192
197 | | 192
Erwin dit
Plusieurs caractères ne sont pas destinés à être affichés. Donc, encodez avant de stocker et de décoder avant d'afficher ...
Je ne sais pas pourquoi nous devrions coder du tout si nous faisons exactement ce que cette question demande
CREATE TABLE foo AS
SELECT i::"char"
FROM generate_series(-128,127) i;
Ça marche bien. Nous pouvons récupérer les ints en utilisant
SELECT i::int FROM foo;
Bref,
- Que fait le code d'Erwin entre 10 et 11 où le i devient nul?
- Pourquoi 128 est-il répété autant de fois?
- Pourquoi 192 est-il répété autant de fois?
Comment puis-je déclencher l'incapacité à stocker 0, quand Erwin dit que vous ne pouvez pas coder 0 de cette façon (caractère nul non autorisé)
CREATE TABLE foo AS SELECT 0::int::"char" AS x; SELECT x::int FROM foo; x --- 0
la source
psql
est un bug ou quelque chose de bizarre. Il termine la ligne, puis saute une ligne?Pour effectuer le passage à la plage signée, vous pouvez créer certaines fonctions pour vous aider. Cette liste va créer des fonctions non moulages pour aider à aider dans ce processus de passer d' une gamme int un octet non signé
[0-255]
à une plage d' un octet signé ce caractère exige de[-128,127]
.pguint
fournit un typeuint1
qui prévoit le stockage sous la forme d'un entier non signé sur un octet. Si vous êtes capable de compiler et d'installer des extensions, vous devriez considérer cela.pg_uchar
. Vous pouvez trouver leinstall.sql
fichier dans ce référentiel.Exemple
Un extrait du README
Maintenant, vous pouvez par exemple stocker les valeurs dans la plage de
[0-255]
sur la table.Convertissez-les en
bit(8)
Peut-être que vous voulez effacer les deux bits de poids faible, vous pouvez le faire avec BITWISE-AND,
la source