Description
HiveText lit et écrit le format de sérialisation texte utilisé par les tables Apache Hive
(format produit par le LazySimpleSerDe de Hive). Il s’agit d’un format texte
délimité, semblable à CSV, dans lequel les champs sont
séparés par le délimiteur Hive par défaut \x01 (Ctrl-A). Le délimiteur de champ est
configurable via input_format_hive_text_fields_delimiter.
Lorsqu’il est utilisé comme format d’entrée, les données n’ont pas de ligne d’en-tête : les valeurs sont
associées aux colonnes de la table de destination selon leur position, de sorte que les noms et les types des
colonnes sont repris de la table (ou d’une structure explicitement fournie)
plutôt qu’inférés à partir des données. Lors de la lecture, ClickHouse analyse les
dates et heures en mode best-effort (voir date_time_input_format),
complète les champs de fin omis avec les valeurs par défaut des colonnes et ignore les champs qu’il ne
reconnaît pas.
Dans un champ, les valeurs sont analysées à l’aide des mêmes règles d’échappement que CSV, plutôt
que des délimiteurs imbriqués de Hive. En particulier, une colonne de type
Array est lue à partir de la
représentation entre crochets (par exemple, "['a','b','c']"), et non à partir de valeurs séparées par
le délimiteur de collection Hive \x02.
Les paramètres de délimiteurs imbriqués n’ont aucun effet sur l’entréeLes paramètres
input_format_hive_text_collection_items_delimiter et
input_format_hive_text_map_keys_delimiter
sont acceptés pour des raisons de compatibilité, mais ne sont actuellement pas utilisés lors de l’analyse. Ils sont toutefois utilisés lors de l’écriture de valeurs imbriquées en sortie.input_format_hive_text_allow_variable_number_of_columns) :
pour les lignes comportant moins de champs que la table, les colonnes manquantes sont remplies avec des
valeurs par défaut, et pour les lignes comportant des champs supplémentaires en fin de ligne, ces champs sont ignorés.
Exemple d’utilisation
,) à l’aide de
input_format_hive_text_fields_delimiter, afin de rendre les fichiers d’entrée
plus faciles à lire.
Lecture d’un fichier HiveText
hive_data.txt avec des champs séparés par des virgules :
hive_data.txt
FORMAT HiveText :
Query
Response
1,3, ne contient que deux champs ; la colonne manquante c
est donc renseignée avec sa valeur par défaut 0.
Nombre variable de colonnes
input_format_hive_text_allow_variable_number_of_columns = 1,
les lignes qui comportent plus de champs que la table n’a de colonnes voient simplement les champs
supplémentaires en fin de ligne ignorés :
hive_extras.txt
Query
Response
input_format_hive_text_allow_variable_number_of_columns = 0 à la place
impose un nombre strict de champs, et une ligne comportant moins de champs que la table déclenche
une exception d’analyse.
Sortie
HiveText écrit chaque ligne sans guillemets :
les champs de niveau supérieur sont séparés par le délimiteur de champs (\x01 par défaut) et
les lignes sont séparées par le délimiteur de lignes (\n par défaut, configurable via
format_hive_text_rows_delimiter). Les valeurs des types imbriqués
(Array, Map
et Tuple) sont écrites sans crochets et
séparées par le séparateur Hive correspondant à leur niveau d’imbrication, comme le fait
LazySimpleSerDe de Hive. Les trois premiers séparateurs sont le délimiteur de champs configurable,
input_format_hive_text_collection_items_delimiter
(\x02 par défaut, utilisé pour les éléments de tableau, les entrées de map et les éléments de tuple) et
input_format_hive_text_map_keys_delimiter (\x03 par défaut,
utilisé entre une clé de map et sa valeur) ; les niveaux plus profonds utilisent par défaut des caractères de contrôle
consécutifs (\x04, \x05, et ainsi de suite, jusqu’à huit niveaux). Un arbre de types imbriqué
assez profondément pour nécessiter un séparateur au-delà de ces huit niveaux est rejeté avec une
exception NOT_IMPLEMENTED, car le LazySimpleSerDe de Hive ne dispose pas non plus de séparateur pour
ce cas. Les types de données qui n’ont pas de représentation textuelle
naturelle dans Hive ne sont pas pris en charge en sortie et génèrent une
exception NOT_IMPLEMENTED. Cela inclut AggregateFunction, Dynamic,
Variant, LowCardinality et Object, ainsi que les types à représentation numérique
Enum, Time, Time64 et Interval — Hive ne dispose d’aucun type correspondant pour ces
derniers, qui sont donc rejetés plutôt que d’être écrits sous forme de leurs
valeurs numériques sous-jacentes brutes. Les types numériques de grande taille Int128, UInt128, Int256 et UInt256
sont rejetés pour la même raison : le plus grand entier pris en charge par Hive est BIGINT (64 bits),
et même DECIMAL de Hive, avec sa précision maximale de 38, ne peut pas couvrir leur
plage de valeurs. De même, les valeurs Decimal dont la précision est supérieure à 38 (c’est-à-dire
Decimal256) dépassent la précision maximale de DECIMAL dans Hive et sont rejetées.
De même, les clés de Map doivent être d’un type primitif : Hive déclare les maps
sous la forme MAP<primitive_type, data_type> ; par conséquent, une Map dont le type de clé est un Array,
une Map ou un Tuple (ce que ClickHouse autorise) est rejetée avec une
exception NOT_IMPLEMENTED, car aucun schéma Hive ne pourrait relire de telles valeurs.
Le littéral de map vide map() est rejeté pour la même raison : son type
est Map(Nothing, Nothing), et Nothing n’est pas un type qu’une déclaration Hive
MAP<key_type, data_type> pourrait désigner. Toutes ces vérifications sont appliquées dès le départ aux types de colonnes déclarés, avant
l’écriture de toute ligne : une requête dont l’en-tête contient un type non pris en charge à n’importe quel endroit
de son arbre de types est rejetée, même lorsque les valeurs réelles n’atteindraient jamais la
sérialisation non prise en charge (par exemple, un Nullable d’un type non pris en charge
ne contenant que des valeurs NULL, ou un Array/Map vide dont le type d’élément n’est pas pris en charge),
car le schéma déclaré du fichier ne pourrait toujours correspondre à aucune table
Hive.
Date, Date32, DateTime et DateTime64 sont toujours écrits au format texte simple
de date et d’horodatage de Hive (yyyy-MM-dd et yyyy-MM-dd HH:mm:ss[.fffffffff]),
indépendamment du paramètre date_time_output_format,
afin que la sortie reste analysable par Hive même lorsque ce paramètre vaut
unix_timestamp ou iso.
Pour la même raison, les valeurs Bool sont toujours écrites sous la forme true/false,
indépendamment des paramètres bool_true_representation
et bool_false_representation,
et les valeurs NULL sont toujours écrites sous la forme de la séquence nulle par défaut de Hive
\N, indépendamment du paramètre format_csv_null_representation.
Cela garantit que la sortie reste lisible par le LazySimpleSerDe de Hive, quels que soient
ces paramètres de texte génériques. De même, le format d’entrée HiveText
interprète toujours \N comme NULL, indépendamment du paramètre
format_csv_null_representation,
afin que l’aller-retour des valeurs scalaires de niveau supérieur n’en dépende pas.
Les valeurs non finies Float32 et Float64 sont écrites avec les graphies Java de Hive
NaN, Infinity et -Infinity, plutôt qu’avec les jetons habituels de ClickHouse nan/inf/-inf,
afin que l’analyseur FLOAT/DOUBLE de Hive les relise en tant que mêmes valeurs
plutôt que comme NULL.
Sortie compatible avec Hive, mais pas d’aller-retour complet via le format d’entréeLa sortie cible le
LazySimpleSerDe par défaut de Hive et n’est pas symétrique avec
l’entrée HiveText de ClickHouse :- Les valeurs
Array,MapetTupleimbriquées sont écrites avec les séparateurs imbriqués de Hive (sans crochets), mais le format d’entrée analyse chaque champ selon les règlesCSV/avec crochets et ignoreinput_format_hive_text_collection_items_delimiter/input_format_hive_text_map_keys_delimiter. Ainsi, une sortie imbriquée telle queSELECT [1, 2] FORMAT HiveTextn’est pas relue parINSERT ... FORMAT HiveText— seuls les champs scalaires de niveau supérieur peuvent effectuer un aller-retour, et uniquement avec le délimiteur de ligne\npar défaut (voir le point suivant). - L’aller-retour exige également le délimiteur de ligne
\npar défaut. Lorsqueformat_hive_text_rows_delimiterest modifié, la sortie sépare les lignes avec l’octet configuré, mais le format d’entrée reste leCSVRowInputFormatbasé sur les sauts de ligne et il n’existe aucuninput_format_hive_text_rows_delimitercorrespondant. Ainsi, une sortie scalaire sur plusieurs lignes telle queSELECT number FROM numbers(3) FORMAT HiveText SETTINGS format_hive_text_rows_delimiter=';'(qui produit0;1;2;) n’est pas relue parINSERT ... FORMAT HiveTextsous forme de trois lignes. - Seul le sous-ensemble
LazySimpleSerDepar défaut, sans échappement, est implémenté. Les champs sont écrits sans échappement (il n’existe aucun équivalent de l’option HiveROW FORMAT DELIMITED ... ESCAPED BY), etNULLest toujours écrit sous la forme\N(il n’existe aucun équivalent deNULL DEFINED AS). UneStringqui contient elle-même un séparateur actif de champ, de ligne ou imbriqué est donc écrite littéralement et sera mal interprétée lors de la réanalyse — ce qui correspond au comportement de Hive avec une serde sans échappement. Pour la même raison, uneStringdont la valeur est littéralement\N(par exempleSELECT '\\N'::String FORMAT HiveText) est écrite avec les mêmes deux octets qu’un véritableNULL, de sorte que les deux sont indiscernables côté Hive.
Query