| 1 |
<!-- |
|---|
| 2 |
$Header: /cvsroot/pgsql-fr/sgml/extend.sgml,v 1.1 2003/08/15 13:41:51 guillaume |
|---|
| 3 |
Exp $--> |
|---|
| 4 |
|
|---|
| 5 |
<chapter id="extend"> |
|---|
| 6 |
<title>Extension de <acronym>SQL</acronym></title> |
|---|
| 7 |
|
|---|
| 8 |
<indexterm zone="extend"> |
|---|
| 9 |
<primary>Extension de SQL</primary> |
|---|
| 10 |
</indexterm> |
|---|
| 11 |
|
|---|
| 12 |
<para> |
|---|
| 13 |
Dans cette section, nous discutons de la façon d'étendre le langage de |
|---|
| 14 |
requêtes <productname>PostgreSQL</productname> en ajoutant des : |
|---|
| 15 |
<itemizedlist spacing="compact" mark="bullet"> |
|---|
| 16 |
<listitem> |
|---|
| 17 |
<para> |
|---|
| 18 |
fonctions (commençant à la <xref linkend="xfunc">) ; |
|---|
| 19 |
</para> |
|---|
| 20 |
</listitem> |
|---|
| 21 |
<listitem> |
|---|
| 22 |
<para> |
|---|
| 23 |
agrégats (commençant à la <xref linkend="xaggr">) ; |
|---|
| 24 |
</para> |
|---|
| 25 |
</listitem> |
|---|
| 26 |
<listitem> |
|---|
| 27 |
<para> |
|---|
| 28 |
types de données (commençant à la <xref linkend="xtypes">) ; |
|---|
| 29 |
</para> |
|---|
| 30 |
</listitem> |
|---|
| 31 |
<listitem> |
|---|
| 32 |
<para> |
|---|
| 33 |
opérateurs (commençant à la <xref linkend="xoper">) ; |
|---|
| 34 |
</para> |
|---|
| 35 |
</listitem> |
|---|
| 36 |
<listitem> |
|---|
| 37 |
<para> |
|---|
| 38 |
classes d'opérateurs pour les index (commençant à la |
|---|
| 39 |
<xref linkend="xindex">). |
|---|
| 40 |
</para> |
|---|
| 41 |
</listitem> |
|---|
| 42 |
</itemizedlist> |
|---|
| 43 |
</para> |
|---|
| 44 |
|
|---|
| 45 |
<sect1 id="extend-how"> |
|---|
| 46 |
<title>Comment fonctionne l'extensibilité</title> |
|---|
| 47 |
|
|---|
| 48 |
<para> |
|---|
| 49 |
<productname>PostgreSQL</productname> est extensible parce qu'il opère |
|---|
| 50 |
grâce à un catalogue. Si vous êtes familier avec les systèmes standards de |
|---|
| 51 |
bases de données, vous savez qu'ils enregistrent les informations |
|---|
| 52 |
concernant les bases de données, les tables, les colonnes, etc., dans ce |
|---|
| 53 |
qu'on nomme communément des catalogues systèmes (certains systèmes appellent |
|---|
| 54 |
cela le dictionnaire de données). Pour l'utilisateur, les catalogues |
|---|
| 55 |
apparaissent comme des tables ordinaires mais le <acronym>SGBD</acronym> |
|---|
| 56 |
y enregistre ses écritures internes. Une différence essentielle entre |
|---|
| 57 |
<productname>PostgreSQL</productname> et les systèmes de bases de données |
|---|
| 58 |
relationnelles est que <productname>PostgreSQL</productname> enregistre |
|---|
| 59 |
beaucoup plus d'informations dans ses catalogues : pas seulement |
|---|
| 60 |
l'information à propos des tables et des colonnes, mais aussi |
|---|
| 61 |
l'information au sujet des types de données, des fonctions, des méthodes |
|---|
| 62 |
d'accès, etc. Ces tables peuvent être modifiées par l'utilisateur et, |
|---|
| 63 |
puisque <productname>PostgreSQL</productname> fonde ses opérations sur ces |
|---|
| 64 |
tables, cela signifie que <productname>PostgreSQL</productname> peut être |
|---|
| 65 |
étendu par les utilisateurs. En comparaison, les systèmes de bases de |
|---|
| 66 |
données conventionnels peuvent seulement être étendus en modifiant les |
|---|
| 67 |
procédures dans le code source ou en installant des modules spécifiquement |
|---|
| 68 |
écrits par le vendeur de <acronym>SGBD</acronym>. |
|---|
| 69 |
</para> |
|---|
| 70 |
|
|---|
| 71 |
<para>Encore mieux, le serveur <productname>PostgreSQL</productname> peut |
|---|
| 72 |
s'ajouter du code écrit par l'utilisateur grâce au chargement |
|---|
| 73 |
dynamique. C'est-à-dire que l'utilisateur peut spécifier un fichier de code |
|---|
| 74 |
objet (par exemple une bibliothèque partagée) qui implémente un nouveau |
|---|
| 75 |
type ou une nouvelle fonction et que <productname>PostgreSQL</productname> |
|---|
| 76 |
chargera à la demande. Il est encore plus évident d'ajouter au serveur du |
|---|
| 77 |
code écrit en <acronym>SQL</acronym>. Cette possibilité de modifier son |
|---|
| 78 |
fonctionnement <quote>à la volée</quote> fait de |
|---|
| 79 |
<productname>PostgreSQL</productname> un outil unique pour le prototypage |
|---|
| 80 |
rapide de nouvelles applications et de structures de stockage. |
|---|
| 81 |
</para> |
|---|
| 82 |
|
|---|
| 83 |
</sect1> |
|---|
| 84 |
|
|---|
| 85 |
<sect1 id="extend-type-system"> |
|---|
| 86 |
<title>Système de typage de <productname>PostgreSQL</productname></title> |
|---|
| 87 |
|
|---|
| 88 |
<indexterm zone="extend-type-system"> |
|---|
| 89 |
<primary>type de base</primary> |
|---|
| 90 |
</indexterm> |
|---|
| 91 |
|
|---|
| 92 |
<indexterm zone="extend-type-system"> |
|---|
| 93 |
<primary>type de données</primary> |
|---|
| 94 |
<secondary>base</secondary> |
|---|
| 95 |
</indexterm> |
|---|
| 96 |
|
|---|
| 97 |
<indexterm zone="extend-type-system"> |
|---|
| 98 |
<primary>type composé</primary> |
|---|
| 99 |
</indexterm> |
|---|
| 100 |
|
|---|
| 101 |
<indexterm zone="extend-type-system"> |
|---|
| 102 |
<primary>type de données</primary> |
|---|
| 103 |
<secondary>composé</secondary> |
|---|
| 104 |
</indexterm> |
|---|
| 105 |
|
|---|
| 106 |
<para> |
|---|
| 107 |
Les types de données de <productname>PostgreSQL</productname> sont répartis en types de base, |
|---|
| 108 |
types composé, types de domaine et pseudo-types. |
|---|
| 109 |
</para> |
|---|
| 110 |
|
|---|
| 111 |
<para> |
|---|
| 112 |
Les types de base sont ceux qui, comme <type>int4</type>, sont implémentés |
|---|
| 113 |
sous le niveau du langage <acronym>SQL</acronym> (typiquement dans un |
|---|
| 114 |
langage de bas niveau comme le C). Ils correspondent généralement à ce qui |
|---|
| 115 |
est souvent connu comme des types de données abstraits. |
|---|
| 116 |
<productname>PostgreSQL</productname> peut opérer sur de tels types |
|---|
| 117 |
seulement au moyen de fonctions fournies par l'utilisateur et n'en comprend |
|---|
| 118 |
le fonctionnement que dans la mesure où l'utilisateur les décrit. Les types |
|---|
| 119 |
de base sont divisés en types scalaires et types tableaux. Pour chaque type |
|---|
| 120 |
scalaire, un type tableau est automatiquement créé. Ce type tableau peut |
|---|
| 121 |
contenir des tableaux à taille variable du type scalaire correspondant. |
|---|
| 122 |
</para> |
|---|
| 123 |
|
|---|
| 124 |
<para> |
|---|
| 125 |
Les types composés, ou types lignes, sont créés chaque fois qu'un |
|---|
| 126 |
utilisateur crée une table ; il est aussi possible de définir un type |
|---|
| 127 |
composé autonome sans table associée. Un type composé est simplement |
|---|
| 128 |
une liste de types de base avec des noms de champs associés. Une valeur pour |
|---|
| 129 |
un type composé correspond à une ligne ou un enregistrement de valeurs de |
|---|
| 130 |
champ. L'utilisateur peut accéder à ces champs à partir de requêtes |
|---|
| 131 |
<acronym>SQL</>. |
|---|
| 132 |
</para> |
|---|
| 133 |
|
|---|
| 134 |
<para> |
|---|
| 135 |
Un type de domaine est basé sur un type de base particulier et il est |
|---|
| 136 |
interchangeable à de multiples fins avec son type de base. Toutefois, un |
|---|
| 137 |
domaine peut avoir des contraintes qui restreignent ses valeurs valides à un |
|---|
| 138 |
sous-ensemble de ce qui est permis par le type de base sous-jacent. Les |
|---|
| 139 |
domaines peuvent être créés par de simples commandes <acronym>SQL</>. |
|---|
| 140 |
</para> |
|---|
| 141 |
|
|---|
| 142 |
<para> |
|---|
| 143 |
Enfin, il existe quelques <quote>pseudo-types</> pour des besoins |
|---|
| 144 |
particuliers. Les pseudo-types ne peuvent pas apparaître comme des champs de |
|---|
| 145 |
table ou des types composés, mais ils peuvent être utilisés pour déclarer |
|---|
| 146 |
les types des arguments et des résultats de fonctions. Dans le système de |
|---|
| 147 |
typage, ils fournissent un mécanisme pour identifier des classes spéciales de |
|---|
| 148 |
fonctions. La <xref linkend="datatype-pseudotypes-table"> donne la liste des |
|---|
| 149 |
pseudo-types existants. |
|---|
| 150 |
</para> |
|---|
| 151 |
|
|---|
| 152 |
<sect2 id="types-polymorphic"> |
|---|
| 153 |
<title>Types et fonctions polymorphes</title> |
|---|
| 154 |
|
|---|
| 155 |
<indexterm> |
|---|
| 156 |
<primary>types polymorphes</primary> |
|---|
| 157 |
</indexterm> |
|---|
| 158 |
|
|---|
| 159 |
<indexterm> |
|---|
| 160 |
<primary>fonctions polymorphes</primary> |
|---|
| 161 |
</indexterm> |
|---|
| 162 |
|
|---|
| 163 |
<para> |
|---|
| 164 |
Deux pseudo-types particulièrement intéressants sont <type>anyelement</> et |
|---|
| 165 |
<type>anyarray</>, collectivement appelés <firstterm>types polymorphes</>. |
|---|
| 166 |
Toute fonction déclarée utilisant ces types est dite <firstterm>fonction |
|---|
| 167 |
polymorphe</>. Une fonction polymorphe peut opérer sur de nombreux et |
|---|
| 168 |
différents types de données, les types de données spécifiques étant |
|---|
| 169 |
déterminés par les types des données réellement passés lors d'un appel |
|---|
| 170 |
particulier de la fonction. |
|---|
| 171 |
</para> |
|---|
| 172 |
|
|---|
| 173 |
<para> |
|---|
| 174 |
Les arguments et les résultats polymorphes sont liés les uns aux autres et |
|---|
| 175 |
sont résolus dans un type de données spécifique quand une requête faisant |
|---|
| 176 |
appel à une fonction polymorphe est analysée. Chaque occurrence déclarée |
|---|
| 177 |
comme <type>anyelement</type> (soit argument, soit valeur renvoyée par la |
|---|
| 178 |
fonction) peut prendre n'importe quel type réel de données mais, lors d'un |
|---|
| 179 |
appel de fonction donné, elles doivent toutes avoir le |
|---|
| 180 |
<emphasis>même</emphasis> type réel. Chaque occurrence déclarée comme |
|---|
| 181 |
<type>anyarray</type> peut prendre n'importe quel type de données tableau |
|---|
| 182 |
mais, de la même façon, elles doivent toutes être du |
|---|
| 183 |
<emphasis>même</emphasis> type. Si des occurrences sont déclarées comme |
|---|
| 184 |
<type>anyarray</type> et d'autres comme <type>anyelement</type>, le type |
|---|
| 185 |
de tableau réel des occurrences <type>anyarray</type> doit être un tableau |
|---|
| 186 |
dont les éléments sont du même type que ceux apparaissant dans les |
|---|
| 187 |
occurrences de type <type>anyelement</type>. |
|---|
| 188 |
</para> |
|---|
| 189 |
|
|---|
| 190 |
<para> |
|---|
| 191 |
Ainsi, quand plus d'une occurrence d'argument est déclarée avec un type |
|---|
| 192 |
polymorphe, l'effet direct est que seulement certaines combinaisons de |
|---|
| 193 |
types réels d'argument sont autorisées. Par exemple, une fonction déclarée |
|---|
| 194 |
comme <literal>foo(anyelement, anyelement)</> prendra en argument |
|---|
| 195 |
n'importe quelles valeurs en argument à condition qu'elles soient du même |
|---|
| 196 |
type de données. |
|---|
| 197 |
</para> |
|---|
| 198 |
|
|---|
| 199 |
<para> |
|---|
| 200 |
Quand la valeur renvoyée par une fonction est déclarée de type polymorphe, |
|---|
| 201 |
il doit exister au moins une occurrence d'argument également polymorphe, et |
|---|
| 202 |
le type réel de donnée passé comme argument détermine le type réel de |
|---|
| 203 |
résultat renvoyé lors de cet appel à la fonction. Par exemple, s'il |
|---|
| 204 |
n'existait pas déjà un mécanisme d'extraction d'éléments (indexation) de |
|---|
| 205 |
tableau, on pourrait définir une fonction qui implémente ce mécanisme comme |
|---|
| 206 |
ceci : <literal>indice(anyarray, integer) returns anyelement</>. La |
|---|
| 207 |
déclaration de fonction contraint le premier argument réel à être de type |
|---|
| 208 |
tableau et permet à l'analyseur d'inférer le type correct de résultat à |
|---|
| 209 |
partir du type réel du premier argument. |
|---|
| 210 |
</para> |
|---|
| 211 |
</sect2> |
|---|
| 212 |
|
|---|
| 213 |
<sect2> |
|---|
| 214 |
<title>Types de base</title> |
|---|
| 215 |
|
|---|
| 216 |
<para> |
|---|
| 217 |
Les types de base sont ceux implémentés avant le langage |
|---|
| 218 |
<acronym>SQL</> comme <type>int4</type> (typiquement dans un langage de |
|---|
| 219 |
bas niveau comme le C). Ils correspondent généralement à ce qu'on nomme |
|---|
| 220 |
les types de données abstraits. <productname>PostgreSQL</productname> peut |
|---|
| 221 |
opérer avec de tels types seulement au travers de fonctions apportées par |
|---|
| 222 |
l'utilisateur et comprend uniquement le comportement de tels types par la |
|---|
| 223 |
description qu'en a fait l'utilisateur. Les types de base sont ensuite |
|---|
| 224 |
sous-divisés en types scalaires et tableaux. Pour chaque type scalaire, un |
|---|
| 225 |
type de tableau correspondant est automatiquement créé, pouvant contenir |
|---|
| 226 |
des tableaux à la taille des variables de ce type scalaire. |
|---|
| 227 |
</para> |
|---|
| 228 |
|
|---|
| 229 |
</sect2> |
|---|
| 230 |
|
|---|
| 231 |
<sect2> |
|---|
| 232 |
<title>Types composites</title> |
|---|
| 233 |
|
|---|
| 234 |
<para> |
|---|
| 235 |
Les types composites, ou types lignes, sont crées lorsqu'un utilisateur |
|---|
| 236 |
crée une table ; il est aussi possible de définir un type composite se |
|---|
| 237 |
suffisant à lui-même (<quote>stand-alone</>) sans table associée. Un type |
|---|
| 238 |
composite est simplement une liste de types de base avec les noms des |
|---|
| 239 |
champs associés. Une valeur d'un type composite est une ligne ou un |
|---|
| 240 |
enregistrement de champs. L'utilisateur peut accéder aux champs du |
|---|
| 241 |
composant à partir de requêtes <acronym>SQL</>. |
|---|
| 242 |
</para> |
|---|
| 243 |
|
|---|
| 244 |
</sect2> |
|---|
| 245 |
|
|---|
| 246 |
<sect2> |
|---|
| 247 |
<title>Domaines</title> |
|---|
| 248 |
|
|---|
| 249 |
<para> |
|---|
| 250 |
Un domaine est basé sur un type de base particulier et est interchangeable |
|---|
| 251 |
pour de nombreux buts avec son type de base. Néanmoins, un domaine pourrait |
|---|
| 252 |
avoir des contraintes restreignant ses valeurs valides à un sous-ensemble |
|---|
| 253 |
du type de base de départ. |
|---|
| 254 |
</para> |
|---|
| 255 |
|
|---|
| 256 |
<para> |
|---|
| 257 |
Les domaines peuvent être créés avec les commandes <acronym>SQL</> |
|---|
| 258 |
<command>CREATE DOMAIN</command>. Leur création et utilisation ne sont pas |
|---|
| 259 |
discutées dans ce chapitre. |
|---|
| 260 |
</para> |
|---|
| 261 |
</sect2> |
|---|
| 262 |
|
|---|
| 263 |
<sect2> |
|---|
| 264 |
<title>Pseudo-Types</title> |
|---|
| 265 |
|
|---|
| 266 |
<para> |
|---|
| 267 |
Il existe quelques <quote>pseudo-types</> pour certains buts très |
|---|
| 268 |
spécifiques. Les pseudo-types ne peuvent pas apparaître comme colonnes de |
|---|
| 269 |
tables ou d'attributs de types composés, mais peuvent être utilisés pour |
|---|
| 270 |
déclarer les types d'argument ou de résultat de fonctions. Cela fournit un |
|---|
| 271 |
mécanisme à l'intérieur du système de types pour identifier les classes |
|---|
| 272 |
spéciales de fonctions. Le <xref linkend="datatype-pseudotypes-table"> liste |
|---|
| 273 |
les pseudos-types existants. |
|---|
| 274 |
</para> |
|---|
| 275 |
|
|---|
| 276 |
</sect2> |
|---|
| 277 |
|
|---|
| 278 |
<sect2 id="extend-types-polymorphic"> |
|---|
| 279 |
<title>Types polymorphiques</title> |
|---|
| 280 |
|
|---|
| 281 |
<indexterm zone="extend-types-polymorphic"> |
|---|
| 282 |
<primary>type polymorphique</primary> |
|---|
| 283 |
</indexterm> |
|---|
| 284 |
|
|---|
| 285 |
<indexterm zone="extend-types-polymorphic"> |
|---|
| 286 |
<primary>fonction polymorphique</primary> |
|---|
| 287 |
</indexterm> |
|---|
| 288 |
|
|---|
| 289 |
<indexterm zone="extend-types-polymorphic"> |
|---|
| 290 |
<primary>type</primary> |
|---|
| 291 |
<secondary>polymorphique</secondary> |
|---|
| 292 |
</indexterm> |
|---|
| 293 |
|
|---|
| 294 |
<indexterm zone="extend-types-polymorphic"> |
|---|
| 295 |
<primary>fonction</primary> |
|---|
| 296 |
<secondary>polymorphique</secondary> |
|---|
| 297 |
</indexterm> |
|---|
| 298 |
|
|---|
| 299 |
<para> |
|---|
| 300 |
Deux pseudo-types d'un grand intérêt sont <type>anyelement</> et |
|---|
| 301 |
<type>anyarray</>, collectivement appelés des <firstterm>types |
|---|
| 302 |
polymorphiques</>. Toute fonction déclarée utilisant ces types est dite |
|---|
| 303 |
être une <firstterm>fonction polymorphique</>. Une fonction polymorphique |
|---|
| 304 |
peut opérer sur différents types de données, les types de données |
|---|
| 305 |
spécifiques étant déterminés par les types de données réellement passés |
|---|
| 306 |
lors d'un appel particulier. |
|---|
| 307 |
</para> |
|---|
| 308 |
|
|---|
| 309 |
<para> |
|---|
| 310 |
Les arguments et résultats polymorphiques sont liés les uns aux autres et |
|---|
| 311 |
sont modifiés en un type spécifique de données lorsqu'une requête appelant |
|---|
| 312 |
une fonction polymorphique est analysée. Chaque position (argument ou |
|---|
| 313 |
valeur de retour) déclarée en tant que <type>anyelement</type> est |
|---|
| 314 |
autorisée à avoir tout type de donnée spécifique mais, sur un seul appel, |
|---|
| 315 |
elles doivent toutes avoir le <emphasis>même</emphasis> type. Chaque |
|---|
| 316 |
position déclarée comme <type>anyarray</type> peut avoir n'importe quel |
|---|
| 317 |
type de données mais, de façon similaire, elles doivent toutes avoir le même |
|---|
| 318 |
type. Si des positions sont déclarées <type>anyarray</type> et d'autres |
|---|
| 319 |
<type>anyelement</type>, le type de tableau réel dans les positions |
|---|
| 320 |
<type>anyarray</type> doit être un tableau dont les éléments sont du même |
|---|
| 321 |
type que ceux des positions <type>anyelement</type>. |
|---|
| 322 |
</para> |
|---|
| 323 |
|
|---|
| 324 |
<para> |
|---|
| 325 |
Du coup, lorsque plus d'un argument est déclaré polymorphique, l'effet est |
|---|
| 326 |
que seules certaines combinaisons de types d'argument sont autorisées. Par |
|---|
| 327 |
exemple, une fonction déclarée de cette façon |
|---|
| 328 |
<literal>foo(anyelement, anyelement)</> prendra seulement deux valeurs en |
|---|
| 329 |
entrées, à condition qu'elles soient du même type. |
|---|
| 330 |
</para> |
|---|
| 331 |
|
|---|
| 332 |
<para> |
|---|
| 333 |
Lorsque la valeur de retour d'une fonction est déclarée polymorphique, il |
|---|
| 334 |
doit exister au moins un argument lui-aussi polymorphique et le type de |
|---|
| 335 |
données fourni en argument détermine le type de données du code de retour |
|---|
| 336 |
pour cet appel. Par exemple, s'il n'existait pas déjà un mécanisme |
|---|
| 337 |
d'abonnement d'un tableau, nous pourrions définir une fonction qui |
|---|
| 338 |
implémente cet abonnement avec <literal>subscript(anyarray, integer) |
|---|
| 339 |
returns anyelement</>. Cette déclaration contraint le premier argument à |
|---|
| 340 |
être de type tableau et permet à l'analyseur d'inférer le bon type de |
|---|
| 341 |
retour à partir du type du premier argument. |
|---|
| 342 |
</para> |
|---|
| 343 |
</sect2> |
|---|
| 344 |
</sect1> |
|---|
| 345 |
|
|---|
| 346 |
&xfunc; |
|---|
| 347 |
&xaggr; |
|---|
| 348 |
&xtypes; |
|---|
| 349 |
&xoper; |
|---|
| 350 |
&xindex; |
|---|
| 351 |
|
|---|
| 352 |
<!-- Keep this comment at the end of the file |
|---|
| 353 |
Local variables: |
|---|
| 354 |
mode:sgml |
|---|
| 355 |
sgml-omittag:nil |
|---|
| 356 |
sgml-shorttag:t |
|---|
| 357 |
sgml-minimize-attributes:nil |
|---|
| 358 |
sgml-always-quote-attributes:t |
|---|
| 359 |
sgml-indent-step:1 |
|---|
| 360 |
sgml-indent-data:t |
|---|
| 361 |
sgml-parent-document:nil |
|---|
| 362 |
sgml-default-dtd-file:"./reference.ced" |
|---|
| 363 |
sgml-exposed-tags:nil |
|---|
| 364 |
sgml-local-catalogs:("/usr/lib/sgml/catalog") |
|---|
| 365 |
sgml-local-ecat-files:nil |
|---|
| 366 |
End: |
|---|
| 367 |
--> |
|---|