Entrée et sortie binaires

Snowflake accepte trois formats binaires ou schémas d’encodage : hex, base64 et UTF-8.

Dans ce chapitre :

Présentation des formats binaires pris en charge

hex (par défaut)

Le format « hex » se réfère au système hexadécimal, ou base 16. Dans ce format, chaque octet est représenté par deux caractères (chiffres de 0 à 9 et lettres allant de A à F). Lors de l’utilisation du format hexadécimal pour effectuer la conversion :

À partir de :

Vers :

Remarques

Binaire

Chaîne

hex utilise des lettres majuscules.

Chaîne

Binaire

hex est insensible à la casse.

hex est le format binaire par défaut.

base64

Le format « base64 » encode les données binaires (ou les données de chaîne) sous forme de caractères ASCII imprimables (lettres, chiffres et signes de ponctuation ou opérateurs mathématiques). (Le schéma d’encodage en base64 est défini dans RFC 4648.)

Les données encodées en Base64 présentent les avantages suivants :

  • Les données encodées en base64 étant du texte ASCII pur, elles peuvent être stockées dans des systèmes prenant en charge les données de type ASCII mais pas les données BINARY. Par exemple, les données binaires représentant de la musique (échantillons numériques) ou les données UTF représentant des caractères en mandarin peuvent être codées sous forme de texte ASCII et stockées dans des systèmes ne prenant en charge que les caractères ASCII.

  • Comme les données encodées en base64 ne contiennent pas de caractères de contrôle (par exemple, des caractères de fin de transmission, des caractères de tabulation), les données encodées en base64 peuvent être transmises et reçues sans risque que les caractères de contrôle puissent être interprétés comme des commandes plutôt que des données. Les données encodées en Base64 sont compatibles avec les modems plus anciens et les autres équipements de télécommunication qui transmettent et reçoivent des données un caractère à la fois (sans en-têtes de paquets ni protocoles indiquant quelles parties d’un paquet sont des données et quelles parties sont des informations de contrôle ou d’en-tête).

Les données encodées en Base64 présentent les inconvénients suivants :

  • La conversion des données entre les représentations binaires et imprimables ASCII consomme des ressources de calcul.

  • Les données encodées en Base64 nécessitent environ 1/3 d’espace de stockage de plus que les données d’origine.

Les détails techniques sur l’encodage sont indiqués ci-dessous pour les lecteurs intéressés :

Détails de l’encodage base64

Chaque groupe de trois octets de 8 bits (un total de 24 bits) de données binaires est réorganisé en quatre groupes de 6 bits chacun (toujours 24 bits). Chacune des 64 combinaisons possibles de 6 bits est représentée par l’un des 64 caractères ASCII imprimables suivants :

  • lettres majuscules (A - Z)

  • lettres minuscules (a - z)

  • chiffres décimaux (0 - 9)

  • +

  • /

De plus, le caractère = est utilisé pour le remplissage si la longueur de l’entrée n’est pas un multiple exact de 3.

Comme les données encodées en base64 ne contiennent pas de caractères d’espacement (espaces, sauts de lignes, etc.), les données encodées en base64 peuvent être mélangées avec des espaces si vous le souhaitez. Par exemple, si l’émetteur ou le récepteur a une longueur de ligne maximale limitée, les données encodées en base64 peuvent être fractionnées en lignes individuelles en ajoutant des caractères de nouvelle ligne sans corrompre les données. Lors de l’utilisation de base64 pour effectuer la conversion :

À partir de :

Vers :

Remarques

Binaire

Chaîne

base64 n’insère pas d’espace ni de saut de ligne.

Chaîne

Binaire

base64 ignore tous les espaces blancs et les sauts de ligne.

UTF-8

Le format UTF-8 fait référence au codage des caractères UTF-8 pour Unicode. Contrairement aux codages hexadécimaux et base64, qui sont des codages binaires à texte, UTF-8 est un codage texte à binaire. Cela signifie que la conversion d’une chaîne vers un format binaire réussit toujours, mais que la conversion inverse peut échouer.

Ce format est pratique pour effectuer une conversion simple entre un format binaire et une chaîne, pour réinterpréter les données sous-jacentes comme l’un ou l’autre type plutôt que d’encoder et décoder réellement.

Paramètres de session pour les valeurs binaires

Il existe deux paramètres de session qui déterminent comment les valeurs binaires sont transmises à l’intérieur et à l’extérieur de Snowflake :

  • BINARY_INPUT_FORMAT:

    Utilisé pour :

    • Effectuer la conversion en binaire dans la version à un argument de TO_CHAR , TO_VARCHAR.

    • Charger des données dans Snowflake (si aucune option de format de fichier n’est spécifiée ; voir ci-dessous pour plus de détails).

    Le paramètre peut être réglé sur “HEX”, “BASE64” ou “UTF-8” (“UTF8” est également autorisé). Les valeurs des paramètres sont insensibles à la casse. La valeur par défaut est “HEX”.

  • BINARY_OUTPUT_FORMAT:

    Utilisé pour :

    • Afficher des jeux de résultats binaires.

    • Effectuer la conversion en chaîne dans la version à un argument de TO_BINARY.

    • Décharger des données depuis Snowflake (si aucune option de format de fichier n’est spécifiée ; voir ci-dessous pour plus de détails).

    Le paramètre peut être réglé sur “HEX” ou “BASE64”. Les valeurs des paramètres sont insensibles à la casse. La valeur par défaut est “HEX”.

    Note

    Comme la conversion du format binaire à la chaîne peut échouer avec le format UTF-8, BINARY_OUTPUT_FORMAT ne peut pas être réglé sur UTF-8. Pour utiliser UTF-8 pour la conversion dans ce cas de figure, utilisez la version à deux arguments de TO_CHAR , TO_VARCHAR.

Les paramètres peuvent être définis aux niveaux du compte, de l’utilisateur et de la session. Exécutez la commande SHOW PARAMETERS pour afficher les paramètres actuels qui s’appliquent à toutes les opérations de la session en cours.

Option de format de fichier pour charger/décharger des valeurs binaires

En plus des paramètres de session binaires d’entrée et de sortie, Snowflake offre l’option de format de fichier BINARY_FORMAT, qui peut être utilisée pour contrôler explicitement le formatage binaire lors du chargement ou du déchargement des données dans les tables Snowflake.

Cette option peut être réglée sur “HEX”, “BASE64” ou “UTF-8” (les valeurs sont insensibles à la casse). L’option concerne à la fois le chargement et le déchargement des données et, comme les autres options de format de fichier, peut être spécifiée de plusieurs façons :

  • Dans un format de fichier nommé, qui peut ensuite être référencé dans une zone de préparation nommée ou directement dans une commande COPY.

  • Dans une zone de préparation nommée, qui peut ensuite être référencée directement dans une commande COPY.

  • Directement dans une commande COPY.

Chargement des données

Lorsqu’il est utilisé pour le chargement des données, BINARY_FORMAT spécifie le format de valeurs binaires dans vos fichiers de données mis en zone de préparation. Cette option annule toute valeur définie pour le paramètre BINARY_INPUT_FORMAT dans la session (voir Paramètres de session pour valeurs binaires ci-dessus).

Si l’option est réglée sur “HEX” ou “BASE64”, le chargement des données peut échouer lorsque les chaînes du fichier de données mis en zone de préparation ne sont pas valides par rapport au format hex ou base64. Dans ce cas, Snowflake retourne une erreur et exécute l’action spécifiée pour l’option de copie ON_ERROR.

Déchargement des données

Lorsqu’elle est utilisée dans le déchargement de données, l’option BINARY_FORMAT spécifie le format appliqué aux valeurs binaires déchargées dans les fichiers situés dans la zone de préparation spécifiée. Cette option annule toute valeur définie pour le paramètre BINARY_OUTPUT_FORMAT dans la session (voir Paramètres de session pour valeurs binaires ci-dessus).

Si l’option est réglée sur UTF-8, le déchargement des données échoue lorsque l’une des valeurs binaires de la table contient des données UTF-8 non valides. Dans ce cas, Snowflake renvoie une erreur.

Exemple d’entrée/de sortie

Les entrées/sorties BINARY peuvent être déroutantes car « ce que vous voyez n’est pas nécessairement ce que vous obtenez ».

Considérons, par exemple, la séquence de code suivante :

CREATE TABLE binary_table (v VARCHAR, b BINARY);
INSERT INTO binary_table (v, b)
    SELECT 'AB', TO_BINARY('AB');
SELECT v, b FROM binary_table;
+----+----+
| V  | B  |
|----+----|
| AB | AB |
+----+----+

Les sorties de la colonne v (VARCHAR) et de la colonne b semblent identiques. Pourtant, la valeur de la colonne b a été convertie en binaire. Pourquoi la valeur de la colonne b semble-t-elle inchangée ?

La réponse est que l’argument de TO_BINARY est traité comme une séquence de chiffres hexadécimaux (même s’il se trouve entre guillemets et ressemble donc à une chaîne) ; les 2 caractères que vous voyez sont en fait interprétés comme une paire de chiffres hexadécimaux représentant 1 octet de données binaires, et non 2 octets de données de chaîne. (Cela n’aurait pas fonctionné si notre « chaîne » d’entrée contenait des caractères autres que des chiffres hexadécimaux ; le résultat aurait été un message d’erreur similaire à « La chaîne “…” n’est pas une chaîne légale codée en hexadécimal ».)

De plus, lorsque des données BINARY sont affichées, elles sont affichées par défaut sous la forme d’une séquence de chiffres hexadécimaux. Ainsi, les données sont entrées sous forme de chiffres hexadécimaux (pas une chaîne) et sont affichées sous forme de chiffres hexadécimaux, de sorte qu’elles semblent inchangées.

En fait, si l’objectif était de stocker la chaîne à deux caractères “AB”, le code était incorrect. Le code approprié utiliserait la fonction HEX_ENCODE pour convertir la chaîne en une séquence de chiffres hexadécimaux (ou utiliserait une autre fonction « encoder » pour effectuer la conversion dans un autre format, tel que base64) avant de stocker les données. Voici des exemples.

Exemple de format hexadécimal (« HEX »)

Pour entrer des données BINARY, vous pouvez les encoder sous la forme d’une chaîne de caractères hexadécimaux. En voici un exemple.

Commencez par créer une table avec une colonne BINARY :

CREATE TABLE demo_binary (b BINARY);

Si vous essayez d’insérer une chaîne « ordinaire » en utilisant la fonction TO_BINARY() pour essayer de la convertir en une valeur BINARY valide, elle échoue :

INSERT INTO demo_binary (b) SELECT TO_BINARY('HELP', 'HEX');

Voici le message d’erreur :

100115 (22000): The following string is not a legal hex-encoded value: 'HELP'

Cette fois, convertissez explicitement l’entrée en une chaîne de chiffres hexadécimaux avant de l’insérer (cela réussira) :

INSERT INTO demo_binary (b) SELECT TO_BINARY(HEX_ENCODE('HELP'), 'HEX');

Maintenant, récupérez les données :

SELECT TO_VARCHAR(b), HEX_DECODE_STRING(TO_VARCHAR(b)) FROM demo_binary;
+---------------+----------------------------------+
| TO_VARCHAR(B) | HEX_DECODE_STRING(TO_VARCHAR(B)) |
|---------------+----------------------------------|
| 48454C50      | HELP                             |
+---------------+----------------------------------+

Comme vous pouvez le constater, la sortie est affichée par défaut en hexadécimal. Pour récupérer la chaîne d’origine, utiliser la fonction HEX_DECODE_STRING (le complément de la fonction HEX_ENCODE_STRING qui était utilisée précédemment pour encoder la chaîne).

Ce qui suit vous aidera à comprendre ce qui se passe en interne :

SELECT 'HELP', HEX_ENCODE('HELP'), b, HEX_DECODE_STRING(HEX_ENCODE('HELP')),
   TO_VARCHAR(b), HEX_DECODE_STRING(TO_VARCHAR(b)) FROM demo_binary;

Sortie :

SELECT 'HELP', HEX_ENCODE('HELP'), b, HEX_DECODE_STRING(HEX_ENCODE('HELP')),
   TO_VARCHAR(b), HEX_DECODE_STRING(TO_VARCHAR(b)) FROM demo_binary;
+--------+--------------------+----------+---------------------------------------+---------------+----------------------------------+
| 'HELP' | HEX_ENCODE('HELP') | B        | HEX_DECODE_STRING(HEX_ENCODE('HELP')) | TO_VARCHAR(B) | HEX_DECODE_STRING(TO_VARCHAR(B)) |
|--------+--------------------+----------+---------------------------------------+---------------+----------------------------------|
| HELP   | 48454C50           | 48454C50 | HELP                                  | 48454C50      | HELP                             |
+--------+--------------------+----------+---------------------------------------+---------------+----------------------------------+

Exemple de format BASE64

Avant de lire cette section, vous pouvez lire la section sur le format hexadécimal ci-dessus. Les concepts de base sont similaires, et la section Format hexadécimal les explique plus en détail.

Commencez par créer une table avec une colonne BINARY :

CREATE TABLE demo_binary (b BINARY);

Insérer une ligne :

INSERT INTO demo_binary (b) SELECT TO_BINARY(BASE64_ENCODE('HELP'), 'BASE64');

Récupérer cette ligne :

SELECT 'HELP', BASE64_ENCODE('HELP'),
   BASE64_DECODE_STRING(BASE64_ENCODE('HELP')),
   TO_VARCHAR(b, 'BASE64'), 
   BASE64_DECODE_STRING(TO_VARCHAR(b, 'BASE64'))
   FROM demo_binary;
+--------+-----------------------+---------------------------------------------+-------------------------+-----------------------------------------------+
| 'HELP' | BASE64_ENCODE('HELP') | BASE64_DECODE_STRING(BASE64_ENCODE('HELP')) | TO_VARCHAR(B, 'BASE64') | BASE64_DECODE_STRING(TO_VARCHAR(B, 'BASE64')) |
|--------+-----------------------+---------------------------------------------+-------------------------+-----------------------------------------------|
| HELP   | SEVMUA==              | HELP                                        | SEVMUA==                | HELP                                          |
+--------+-----------------------+---------------------------------------------+-------------------------+-----------------------------------------------+

Exemple de format UTF-8

Commencez par créer une table avec une colonne BINARY :

CREATE TABLE demo_binary (b BINARY);

Insérer une ligne :

INSERT INTO demo_binary (b) SELECT TO_BINARY('HELP', 'UTF-8');

Récupérer cette ligne :

SELECT 'HELP', TO_VARCHAR(b, 'UTF-8')
   FROM demo_binary;
+--------+------------------------+
| 'HELP' | TO_VARCHAR(B, 'UTF-8') |
|--------+------------------------|
| HELP   | HELP                   |
+--------+------------------------+