Documentation PostgreSQL 14.22 » Annexes » Conformité SQL » Limitations XML et conformité à SQL/XML

Précédent | Niveau supérieur | Suivant
D.2. Fonctionnalités non supportées | Sommaire | Annexe E. Notes de version

## D.3. Limitations XML et conformité à SQL/XML

Des révisions significatives aux spécifications liées à XML dans ISO/IEC 9075-14 (SQL/XML) ont été introduites par SQL:2006. L'implémentation PostgreSQL du type de données XML et des fonctions associées suivent en grande partie l'édition précédente de 2003, avec quelques emprunts dans les éditions suivantes. En particulier :

- Où le standard actuel fournit une famille de types de données XML pour contenir un « document » ou « content » dans des variantes non typées ou typées par schéma XML, et un type `XML(SEQUENCE)` pour contenir des parties arbitraires de contenu XML, PostgreSQL fournit le seul type `xml`, qui peut contenir un « document » ou « content ». Il n'y a aucun équivalent au type « sequence »standard.

- PostgreSQL fournit deux fonctions introduites par SQL:2006, mais dans des variantes qui utilisent le langage XPath 1.0, plutôt que XML Query comme spécifié pour elles dans le standard.

Cette section présente certaines des différences de résultat que vous pourriez rencontrer.

### D.3.1. Les requêtes sont limitées à XPath 1.0

Les fonctions spécifiques à PostgreSQL `xpath()` et `xpath_exists()` requêtent des documents XML en utilisant le langage XPath. PostgreSQL fournit également des variantes pour XPath uniquement des fonctions du standard `XMLEXISTS` et `XMLTABLE`, qui officiellement utilisent le langage XQuery. Pour toutes ces fonctions, PostgreSQL se repose sur la bibliothèque libxml2, qui ne fournit que XPath 1.0.

Il y a une forte connexion entre le langage XQuery et XPath version 2.0 et supérieure : toute expression qui est syntaxiquement valide et s'exécute avec succès avec les deux produisent le même résultat (avec une exception mineure pour les expressions contenant des références de caractères numériques ou des références d'entités prédéfinies, que XQuery remplace par le caractère correspondant alors que XPath n'y touche pas). Mais il n'y a pas une telle connexion entre ces langages et XPath 1.0 ; c'était un précédent langage qui diffère sur de nombreux aspects.

Il y a deux catégories de limitations à garder à l'esprit : la restriction de XQuery à XPath pour les fonctions spécifiées dans le standard SQL ainsi que la restriction de XPath pour la version 1.0 à la fois pour le standard et pour les fonctions PostgreSQL spécifiques.

#### D.3.1.1. Restriction de XQuery à XPath

Les fonctionnalités de XQuery allant au delà de XPath incluent :

- Les expressions XQuery peuvent construire et retourner de nouveaux nœuds XML, en plus de toutes les valeurs XPath possibles. XPath peut créer et retourner des valeurs des types atomiques (nombres, chaînes et ainsi de suite), mais peuvent uniquement retourner des nœuds XML qui étaient déjà présents dans les documents fournis en entrées de l'expression.

- XQuery dispose de concepts pour l'itération, tri et regroupement.

- XQuery permet la déclaration et l'utilisation de fonctions locales.

Les versions récentes de XPath commencent à offrir des possibilités qui se chevauchent avec celle-ci (comme un `for-each` de style fonctionnel, des fonctions anonymes et `parse-xml` pour créer un nœud depuis une chaîne), mais ces fonctionnalités ne sont pas disponibles avant XPath 3.0.

#### D.3.1.2. Restriction de XPath pour la version 1.0

Pour les développeurs familiers avec XQuery et XPath 2.0 ou plus, XPath 1.0 présente un certain nombre de différences :

- Le type fondamental d'une expression XQuery/XPath, la `sequence`, qui peut contenir des nœuds XML, des valeurs atomiques ou les deux, n'existe pas dans XPath 1.0. Une expression 1.0 peut uniquement produire des nœuds-ensemble (contenant zéro ou plus nœuds XML), ou une seule valeur atomique.

- Contrairement à une séquence XQuery/XPath, qui peut contenir n'importe quel élément voulu dans n'importe quel ordre voulu, un nœud-ensemble XPath 1.0 n'a aucune garantie sur l'ordre et, comme n'importe quel ensemble, n'autorise pas de multiples occurrences d'un même élément.

  ### Note

  La bibliothèque libxml2 semble toujours retourner des nœud-ensembles à PostgreSQL avec leurs membres dans le même ordre relatif qu'ils avaient dans le document en entrée. Sa documentation ne valide pas ce comportement, et une expression XPath 1.0 ne peut pas le contrôler.

- Bien que XQuery/XPath fournisse tous les types définis dans XML Schema et de nombreux opérateurs et fonctions au dessus de ces types, XPath 1.0 n'a que le nœud-ensemble et les trois types atomiques `boolean`, `double`, et `string`.

- XPath 1.0 n'a pas d'opérateur conditionnel. Une expression XQuery/XPath telle que `if ( hat ) then hat/@size else "no hat"` n'a pas d'équivalent avec XPath 1.0.

- XPath 1.0 n'a pas d'opérateur de comparaison de tri pour les chaînes de caractère. `"cat" < "dog"` et `"cat" > "dog"` sont tous les deux faux, car chacun est une comparaison numérique de deux `NaN`s. En comparaison, `=` et `!=` comparent les chaînes en tant que chaînes.

- XPath 1.0 brouille la distinction entre value comparisons et general comparisons tels que XQuery/XPath les définis. `sale/@hatsize = 7` et `sale/@customer = "alice"` sont tous les deux existentiellement des comparaisons quantifiées, vraies s'il y a au moins un `sale` avec la valeur donnée pour l'attribut, mais `sale/@taxable = false()` est une comparaison de valeur de la valeur booléenne effective d'un nœud-ensemble entier. C'est uniquement vrai si aucun `sale` n'a un attribut `taxable`.

- Dans le modèle de données XQuery/XPath, un nœud document peut avoir soit une forme de document (c'est-à-dire exactement un élément de premier niveau, avec uniquement des commentaires et des instructions de traitement en dehors de celui-ci) ou une forme de contenu (avec ces contraintes relâchées). Son équivalent dans XPath 1.0, le nœud racine, ne peut être que dans une forme de document. C'est en partie la raison pour laquelle une valeur `xml` passée comme objet de contexte à n'importe laquelle des fonctions PostgreSQL basée sur XPath doit être dans une forme de document.

Les différences mises en évidence ici ne représentent pas l'intégralité des différences. Avec XQuery et les versions 2.0 et supérieures de XPath, il y a un mode de compatibilité XPath 1.0, et les listes W3C de changement de bibliothèques de fonction et de changement du langage appliqués dans ce mode offrent un compte rendu plus complet (mais toujours pas exhaustif) des différences. Le mode de compatibilité ne peut pas rendre les langages supérieurs exactement équivalents à XPath 1.0.

#### D.3.1.3. Correspondances entre types de données et valeurs SQL et XML

Avec SQL:2006 et ultérieur, les deux sens de conversion entre les types de données standard SQL et les types XML Schema sont précisément spécifiés. Cependant, les règles sont exprimées en utilisant les types et sémantiques de XQuery/XPath, et n'ont pas d'application directe pour les différents modèles de XPath 1.0.

Quand PostgreSQL fait correspondre des valeurs de données SQL vers XML (par exemple avec `xmlelement`), ou XML vers SQL (par exemple comme les colonnes en sortie de `xmltable`), à l'exception de quelques cas traités spécifiquement, PostgreSQL part simplement du principe que le type de données XML chaîne de caractère XPath 1.0 sera valide en tant que forme d'entrée texte du type de données SQL, et réciproquement. Cette règle a l'avantage d'être simple tout en produisant, pour de nombreux types de données, des résultats similaires aux correspondances spécifiées dans le standard.

Quand l'interopérabilité avec les autres systèmes est une préoccupation, pour certains types de données, il peut ne pas être nécessaire d'utiliser explicitement des fonctions de formatage de type de données (telles que celles dans Section 9.8) pour produire les correspondances standard.

### D.3.2. Limites accidentelles de l'implémentation

Cette section concerne les limites qui ne sont pas inhérentes à la bibliothèque libxml2, mais qui s'appliquent à l'implémentation actuelle dans PostgreSQL.

#### D.3.2.1. Seul le mécanisme de passage `BY VALUE` est supporté

Le standard SQL définit deux mécanismes de passage qui s'appliquent quand un argument XML est passé de SQL à une fonction XML ou en recevant un résultat : `BY REF`, pour lequel une valeur XML particulière retient son identité de nœud, et `BY VALUE`, pour lequel le contenu du XML est passé mais l'identité du nœud n'est pas préservée. Un mécanisme peut être spécifié avant une liste de paramètres, comme le mécanisme par défaut pour tous ceux-ci, ou après n'importe lequel des paramètres, pour surcharger le mécanisme par défaut.

Pour illustrer la différence, si `x` est une valeur XML, ces deux requêtes dans un environnement SQL:2006 produiraient respectivement vrai et faux :

    SELECT XMLQUERY('$a is $b' PASSING BY REF x AS a, x AS b NULL ON EMPTY);
    SELECT XMLQUERY('$a is $b' PASSING BY VALUE x AS a, x AS b NULL ON EMPTY);

PostgreSQL acceptera `BY VALUE` ou `BY REF` dans une construction `XMLEXISTS` ou `XMLTABLE`, mais les ignorera. Le type de données `xml` a une représentation sérialisée en chaîne de caractères, il n'y a donc pas d'identité de nœud à préserver, et le passage est dans les faits toujours `BY VALUE`.

#### D.3.2.2. Impossibilité de passer des paramètres nommés aux requêtes

Le support des fonctions basées sur XPath supportent de passer un paramètre afin d'être utilisé comme l'item du contexte de l'expression XPath, mais ne supporte pas de passer des valeurs supplémentaires pour être disponibles dans l'expression comme paramètre nommés.

#### D.3.2.3. Pas de type `XML(SEQUENCE)`

Le type de donnéesPostgreSQL `xml` ne peut contenir qu'une valeur dans une forme `DOCUMENT` ou `CONTENT`. Un item de contexte d'expression XQuery/XPath doit être un unique nœud XML ou une valeur atomique, mais XPath 1.0 le restreint en plus à n'être qu'un nœud XML, et n'a aucun type de nœud autorisant `CONTENT`. Le résultat est qu'un `DOCUMENT` formé comme il faut est la seule forme de valeur XML que PostgreSQL peut fournir à un item de contexte XPath.